【发布时间】:2022-05-17 19:02:49
【问题描述】:
如果传递到 user_data 的脚本无法运行,是否有可能创建 aws_instance 失败?例如,1 号出口?
我有一个 null_resource,它使用 depends_on [aws_instance.myVM] 将 JSON 发布到实例,当 user_data 脚本失败时,我需要该 depends_on 失败。
谢谢!
【问题讨论】:
标签: terraform
如果传递到 user_data 的脚本无法运行,是否有可能创建 aws_instance 失败?例如,1 号出口?
我有一个 null_resource,它使用 depends_on [aws_instance.myVM] 将 JSON 发布到实例,当 user_data 脚本失败时,我需要该 depends_on 失败。
谢谢!
【问题讨论】:
标签: terraform
user_data 由在实例本身内部运行的软件处理,例如 cloud-init,因此它的处理与 Terraform 的 AWS 提供商为启动实例运行而进行的 ec2:RunInstances 调用是异步的。因此,无法从user_data 处理反馈状态信息,因为它可能会在 EC2 API 开始报告实例“正在运行”后运行一段时间,具体取决于它在启动过程中的处理位置。
另外,depends_on 用于排序而不是处理错误,因此depends_on 子句永远不会改变 Terraform 的错误处理。
如果您想在您的实例上同步运行软件作为 Terraform 的创建操作的一部分,那么不幸的是,唯一实用的选择是使用 the remote-exec provisioners。这是以相当大的额外复杂性为代价的,因为 Terraform 现在必须能够打开与实例的 SSH 会话并对其进行身份验证以创建双向通信通道。
作为对这种复杂性的回报,Terraform 可以运行相关代码,因此 Terraform 可以检测它是否成功(使用其退出状态)。如果远程命令失败,Terraform 将停止进一步处理,返回错误,并将实例标记为已污染,以便下一个计划将尝试再次创建它。
话虽如此,最好找到一种不同的方法来实现您的目标,而不需要将 Terraform 运行直接耦合到虚拟机中运行的软件的状态。通常不期望 Terraform 配置既需要启动虚拟机并在同一操作中与在该虚拟机中运行的软件交互。这可能是一些系统分解的好点,您将有一个声明虚拟机应该存在的 Terraform 配置,然后是第二个配置,假设虚拟机存在并对其采取措施它。然后,您可以在这两者之间运行您需要运行的任何其他软件,以检查实例是否成功启动。
【讨论】:
我这样做的一个不太明显的方法是在用户数据的末尾将实例注册为领事服务。如果服务从未到达,下游轮询 consul 服务的到达也可能超时并失败。这可以位于另一个可以用作依赖项的本地 exec 函数中,也可以位于其他实例用户数据中。
也许更好的方法是使用 consul KV 存储,而不是仅仅依赖服务到达。 KV 存储可用于提供更多信息,而不仅仅是二进制状态。
【讨论】: