1 terraform state文件
Terraform 的状态文件(Terraform State)是一个 JSON 格式的文件,用于追踪当前基础设施的状态。这个文件记录了 Terraform 管理的资源和它们的属性,以及与这些资源相关联的元数据。状态文件的主要作用是让 Terraform 能够了解当前实际的基础设施状态,从而有效地进行计划(plan)和应用(apply)操作。
默认情况下,Terraform 将状态文件存储在本地文件系统的 .terraform 子目录中。但在实际生产环境中,建议将状态文件存储在外部的可靠存储中,如 Amazon S3,以便实现状态的共享和安全管理。
2 terraform state 相关命令
- list,查看资源列表,
bash
$ terraform state list
aws_s3_bucket.bucket
aws_s3_bucket_policy.bucket_policy
aws_s3_bucket_public_access_block.bucket_public_access_block
- rm,移除资源
这里的移除是指不再通过terraform管理该资源,并不会真正删除该资源,
bash
$ terraform state rm aws_s3_bucket_public_access_block.bucket_public_access_block
Acquiring state lock. This may take a few moments...
Removed aws_s3_bucket_public_access_block.bucket_public_access_block
Successfully removed 1 resource instance(s).
Releasing state lock. This may take a few moments...
$ terraform state list
aws_s3_bucket.bucket
aws_s3_bucket_policy.bucket_policy
删除后可以再把资源加回来,
bash
$ terraform import aws_s3_bucket_public_access_block.bucket_public_access_block my.bucket.name.com
Acquiring state lock. This may take a few moments...
aws_s3_bucket_public_access_block.bucket_public_access_block: Importing from ID "my.bucket.name.com"...
aws_s3_bucket_public_access_block.bucket_public_access_block: Import prepared!
Prepared aws_s3_bucket_public_access_block for import
aws_s3_bucket_public_access_block.bucket_public_access_block: Refreshing state... [id=my.bucket.name.com]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Releasing state lock. This may take a few moments...
$ terraform state list
aws_s3_bucket.bucket
aws_s3_bucket_policy.bucket_policy
aws_s3_bucket_public_access_block.bucket_public_access_block
- pull/push,拉取和推送state状态
比如本地state被修改,想要恢复就可以用pull;想要把本地的修改同步到远端,就使用push。
关于push,有个使用场景,比如我们要修改当前资源在state文件中的key路径,比如原来的定义,
bash
backend "s3" {
bucket = "aaa.com"
key = "lab/tfstate"
dynamodb_table = "tflock-lab"
}
现在由于目录调整,想要移动到lab/reg/tfstate下,我们就可以先把当前资源移除,然后切换到新的目录,执行terraform init操作,然后执行import,最后再把本地state文件push到远端。
- mv,重命名或移动资源
重命名并不会实际修改资源,只是修改terraform中管理的该资源名称,就是改个变量名。比如我修改aws_s3_bucket.bucket,并不会实际修改bucket name,原来的bucket id是my.bucket.name.com,修改后还是my.bucket.name.com
bash
$ terraform state mv aws_s3_bucket.bucket aws_s3_bucket.test_bucket
Acquiring state lock. This may take a few moments...
Move "aws_s3_bucket.bucket" to "aws_s3_bucket.test_bucket"
Successfully moved 1 object(s).
Releasing state lock. This may take a few moments...
$ terraform state list
aws_s3_bucket.test_bucket
移动资源,我们有时候会将某些资源通过mudule来管理,便于复用,就可以将已部署的资源移动到module中,
bash
$ terraform state mv aws_s3_bucket.test_bucket module.s3_bucket.aws_s3_bucket.test_bucket
Acquiring state lock. This may take a few moments...
Move "aws_s3_bucket.test_bucket" to "module.s3_bucket.aws_s3_bucket.test_bucket"
Successfully moved 1 object(s).
Releasing state lock. This may take a few moments...
$ terraform state list
module.s3_bucket.aws_s3_bucket.test_bucket
上面我们将test_bucket移动到名为s3_bucket的module中管理。
3 terraform state lock
状态锁定是一种机制,用于防止多个 Terraform 实例同时修改相同的状态文件,从而避免冲突,多个人同时操作同一个资源时会出现以下报错,
bash
$ terraform apply
Acquiring state lock. This may take a few moments...
╷
│ Error: Error acquiring the state lock
│
│ Error message: ConditionalCheckFailedException: The conditional request failed
│ Lock Info:
│ ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
│ Path: lab/tfstate
│ Operation: OperationTypeApply
│ Who: yourname
│ Version: 1.4.2
│ Created: 2023-11-24 08:53:13.027117 +0000 UTC
│ Info:
│
│
│ Terraform acquires a state lock to protect the state from being written
│ by multiple users at the same time. Please resolve the issue above and try
│ again. For most commands, you can disable locking with the "-lock=false"
│ flag, but this is not recommended.
还有一种情况是,你在执行terraform操作,中间由于网络或者其他异常导致进程异常结束,那这个锁来不及释放,下次执行时也会报这个错,这个时候who中显示的就是你自己的名字,这种情况下我们可以强制解锁。
bash
$ terraform force-unlock xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Do you really want to force-unlock?
Terraform will remove the lock on the remote state.
This will allow local Terraform commands to modify this state, even though it
may still be in use. Only 'yes' will be accepted to confirm.
Enter a value: yes
Terraform state has been successfully unlocked!
The state has been unlocked, and Terraform commands should now be able to
obtain a new lock on the remote state.