Terraform:获取状态锁时出错:ConditionalCheckFailedException

Posted

技术标签:

【中文标题】Terraform:获取状态锁时出错:ConditionalCheckFailedException【英文标题】:Terraform: Error acquiring the state lock: ConditionalCheckFailedException 【发布时间】:2020-09-23 03:41:55 【问题描述】:

我在管道中发生terraform plan 期间收到以下错误:

Error: Error locking state: Error acquiring the state lock: ConditionalCheckFailedException: The conditional request failed
Lock Info:
ID:        9db590f1-b6fe-c5f2-2678-8804f089deba
Path:      ...
Operation: OperationTypePlan
Who:       ...
Version:   0.12.25
Created:   2020-05-29 12:52:25.690864752 +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.

这很奇怪,因为我确定没有其他并发计划。 有没有办法解决这个问题?我应该如何移除这个锁?

【问题讨论】:

【参考方案1】:

错误原因

此错误通常在一个进程运行terraform planterraform apply 失败时出现。例如,如果您的网络连接中断或进程在完成之前终止。然后 Terraform “认为”该进程仍在基础架构上工作,并阻止其他进程同时使用相同的基础架构和状态以避免冲突。

如错误消息中所述,您应该确保确实没有其他进程仍在运行(例如来自其他开发人员或来自某些构建自动化)。如果你在这种情况下强制解锁,你可能会搞砸你的 terraform 状态,使其难以恢复。

分辨率

如果没有其他进程仍在运行:运行此命令

terraform force-unlock 9db590f1-b6fe-c5f2-2678-8804f089deba

(其中数字 id 应替换为错误消息中提到的那个)

如果您不确定是否有另一个进程正在运行并且您担心可能会使事情变得更糟,我建议您等待一段时间(例如 1 小时),然后重试,然后在 30 分钟后重试。如果错误仍然存​​在,则很可能确实没有其他进程,并且如上所述可以安全解锁

【讨论】:

如果我关闭了终端会话,因此无法访问数字 ID,该怎么办 当你尝试做一个需要状态锁的操作时,错误会再次出现,然后你可以得到ID 我尝试强制解锁,但出现此错误,我正在使用 GCS 状态后端。 Failed to unlock state: 2 errors occurred: * storage: object doesn't exist * storage: object doesn't exist【参考方案2】:

看起来锁在上一个管道之后仍然存在。我必须使用以下命令将其删除才能将其删除:

terraform force-unlock -force 9db590f1-b6fe-c5f2-2678-8804f089deba

或者使用以下选项重新启动计划-lock=false

terraform plan -lock=false ...

【讨论】:

【参考方案3】:

即使我遇到了同样的问题并尝试了不同的命令 terraform force-unlock -forceterraform force-unlock 但对我不起作用。该问题的快速解决方法是kill that particular process id and run again

ps aux | grep terraformsudo kill -9 <process_id>

【讨论】:

【参考方案4】:

如果 terraform force-unlock 出现以下错误: “本地状态不能被另一个进程解锁” 然后 打开正在运行的进程并杀死进程以解除锁定。 对于 Windows:打开任务管理器并搜索 terraform 控制台进程 对于 Linux:grep 用于 terraform 进程并使用 kill -9 终止 terraform 控制台进程

【讨论】:

我无法检索锁定信息:JSON 输入意外结束【参考方案5】:

对于在针对 AWS 运行 Terraform 时遇到此问题的任何人,请确保您针对预期的配置文件运行。我今天遇到了这个问题,意识到我需要切换我的个人资料:

$ AWS_PROFILE=another_one

【讨论】:

【参考方案6】:

GCP:在我的情况下,在 Google 云存储中将权限更改为“存储对象管理员”后问题得到解决。

【讨论】:

【参考方案7】:

这是我的 AWS CLI 会话问题,我在命令提示符下使用 gimme-aws-creds 命令重新登录,然后尝试。它奏效了。

【讨论】:

【参考方案8】:

我在 AWS 和我们的管道中遇到了同样的问题。我们正在过渡到 git-actions。我们的 terraform 使用 dynamodb 作为其锁状态持久性,并使用 s3 来保存实际的 terraform 状态文件。在dynamodb中查看锁状态的时候,md5摘要列是空的,key没有指明和-md5,只是一个正常的。

注意:如果您不熟悉 Terraform 状态文件,请勿尝试此操作。

我所做的是克隆了上述锁定状态并重命名为 -md5。查看我的 s3 statefile 中的 hashkey 并将其复制到 dynamo 表中的摘要列。将旧的锁定状态重命名为不同的键,这样就不会被搜索到。

对我来说就是这样。

同样,这可能并不适合所有人,但这对我有用。

【讨论】:

【参考方案9】:

我收到状态锁定错误,因为我缺少 s3:DeleteObjectdynamodb:DeleteItem 权限。

我有获取和放置权限,但没有删除。因此,我的 CircleCI IAM 用户可以检查锁并添加锁,但在完成状态更新后无法删除锁。 (也许我看过使用远程状态但没有使用状态锁定的教程。)

这些步骤解决了这个问题:

    运行terraform force-unlock <error message lock ID>(我从Falk Tandetzkyveben 的答案中得到这一步) 允许"s3:DeleteObject" 对资源"arn:aws:s3:::mybucket/path/to/my/key" 的权限 允许"dynamodb:DeleteItem" 对资源"arn:aws:dynamodb:*:*:table/mytable" 的权限

Terraform S3 后端文档中列出了所有权限和示例:

https://www.terraform.io/language/settings/backends/s3

【讨论】:

以上是关于Terraform:获取状态锁时出错:ConditionalCheckFailedException的主要内容,如果未能解决你的问题,请参考以下文章

地形:获取状态锁时出错:ConditionalCheckFailedException

错误:失败:获取锁时出错:与元存储 org.apache.hadoop.hive.ql.lockmgr.LockException 通信时出错

将现有资源导入 Terraform 状态文件时出错

使用 terraform 创建 lambda 函数时出错获取验证错误

使用 1.1 版初始化 Terraform 时出错

Terraform:导入 aws 资源时出现凭证错误 - 调用 sts 时出错:GetCallerIdentity:ExpiredToken