我手头有以下问题:
我和我的团队正在使用Terraform创建一个AWS EKS集群,我们需要能够在集群内启动新的pod(服务(,而无需更换现有的pod。
这个想法是让一个单独的git存储库保存一个.tfwars文件,每次有人克隆它并推送一个带有编辑版本的新分支时,Terraform都应该创建并启动一个带有更新属性的新Kubernetes pod+创建一个相关的SQS队列。
问题是,无论我是直接将变量传递给资源,还是使用模块,我最终都会得到一个具有不同属性但名称相同的块,因为它不能动态更改,并且原始资源会更新,而不是创建新资源。
资源"kubernetes\deployment"服务"{…
我想到的一个可能的解决方案是使用Terraform Cloud,并将主配置repo和.tfwars repo分离到不同的工作区中,在这些工作区中更新和推送这两者中的任何一个的新分支都会触发运行。
但单独的工作区意味着单独的状态文件,对吗?因此,也许在工作区之间使用共享状态可以解决这个问题
我是Terraform的新手,几天来我一直在思考这个问题,所以任何建议都将不胜感激。
首先:Terraform可能不是您用例的工具,但这是一个有趣的问题。更常见的情况是,将管理一个完整的服务列表,以利用terraform只更新代码/config和现有资源之间的差异的能力。
Terraform想要管理它创建的资源,它认为Terraform路径与该资源唯一匹配。对于您的用例,您需要确保每个服务都有一个唯一的路径。这可以用一个for_each
在一个列表上完成。
我无法从这个问题中判断出你的对象是如何构造的,所以我假设你正在传递一个名为"的对象;服务";具有名为name
:的属性
resource "kubernetes_deployment" "service" {
for_each = [var.service.name]
...
}
现在,不是每个服务都在路径kubernetes_deployment.service
上,而是资源位于路径kubernetes_deployment.service["my_service_name"]
上,其中的名称就是传入的名称
该过程的下一部分是更改调用地形的方式。Terraform使用-target
标志仅更新特定路径上的资源。假设您在名为service_name的环境变量中有服务的名称,则可以使用以下命令:
terraform apply -auto-approve -target="kubernetes_deployment.service["$SERVICE_NAME"]"
这将指示terraform只更新该路径——只要它与你的terraform代码中的有效路径匹配,并且不含糊地指向现有资源,服务就会更新,现有资源不会被触碰。
同样,如果你有机会保留完整的服务列表,那就去做吧。保持完整的列表更接近地形的预期用例。