使用Terraform+Ansible搭建K8s集群时如何仅对单实例执行playbook
问题原因
你将local-exec写在设置了count=3的aws_instance资源块内部,该资源会循环创建3次实例,对应的所有provisioner也会默认跟着执行3次,不符合仅执行1次的需求。
解决方案1:给local-exec加执行条件(快速修改)
直接在你现有local-exec块中添加when条件,仅当count.index为你指定的实例序号时才执行,比如你要给第1台(索引为0)执行,配置示例如下:
provisioner "local-exec" { when = count.index == 0 # 仅在第1个实例的循环流程中执行 command = "ansible-playbook -i ${self.public_ip}, --private-key ${local.private_key_path} helm.yaml" }
该方案直接复用当前循环的实例对象属性,无需额外调用element函数取值,逻辑更简洁。
解决方案2:抽离为独立null_resource(更推荐,逻辑清晰)
把单次执行的操作和实例创建逻辑分离,用null_resource单独实现,避免和实例循环逻辑耦合,后续维护更方便:
# 原有aws_instance资源块不变,删除内部的local-exec块即可 resource "aws_instance" "r100c96" { count = 3 ami = "ami-0b9064170e32bde34" instance_type = "t2.micro" key_name = local.key_name tags = { Name = "terra-ans${count.index}" } provisioner "remote-exec" { connection { host = "${self.public_ip}" type = "ssh" user = local.ssh_user private_key = file(local.private_key_path) } inline = ["sudo hostnamectl set-hostname test"] } } # 新增单独的null_resource执行单次ansible任务 resource "null_resource" "install_helm" { # 等待所有3台实例创建完成后再执行 depends_on = [aws_instance.r100c96] # 可选配置:helm.yaml文件变更时自动重新执行playbook triggers = { playbook_hash = filehash("helm.yaml") } provisioner "local-exec" { command = "ansible-playbook -i ${aws_instance.r100c96[0].public_ip}, --private-key ${local.private_key_path} helm.yaml" } }
注意事项
- 如果需要指定其他实例执行,修改索引值即可,比如选第2台实例就用
aws_instance.r100c96[1].public_ip - 单IP末尾加逗号的写法是正确的,可避免Ansible误将IP字符串识别为本地inventory文件路径
内容的提问来源于stack exchange,提问作者greenszpila
相关产品推荐
相关产品推荐

