Terraform创建EC2后如何自动更新Ansible Inventory为新IP?
问题描述
我在一台EC2实例上部署了Jenkins、Ansible和Terraform,计划创建一个Jenkins任务:先通过Terraform脚本创建新EC2实例,再用Ansible Playbook在该新实例上安装Tomcat。当前遇到的问题是,执行terraform apply时,我希望Inventory文件中仅保留新创建实例的IP,但使用如下main.tf中的local-exec追加命令后,Inventory中会残留多个旧IP:
resource "aws_instance" "my_vm" { ami = var.ami //Linux AMI instance_type = var.instance_type key_name = "DevOpsKey_Licenta" subnet_id = aws_subnet.public_subnet.id vpc_security_group_ids = [aws_security_group.terra_tomcat_sg.id] associate_public_ip_address = true tags = { Name = var.name_tag } provisioner "local-exec" { command = "echo ${aws_instance.my_vm.public_ip} >> /opt/infrastructure-pipeline/inventory" } }
当前Inventory文件内容如下:
[tomcat] 32.153.123.41 12.100.99.3
请问如何实现每次创建新实例时自动更新Inventory为新实例的IP?
解决方案
方法1:修改local-exec命令覆盖文件而非追加
把原来的>>(追加)改成>(覆盖),同时保留[tomcat]分组头,确保每次生成的Inventory只包含最新实例IP:
provisioner "local-exec" { command = "echo -e '[tomcat]\n${aws_instance.my_vm.public_ip}' > /opt/infrastructure-pipeline/inventory" }
执行terraform apply时,该命令会直接覆盖整个Inventory文件,仅保留指定分组和新实例的IP地址。
方法2:使用Terraform模板生成Inventory(更规范)
适合需要扩展Inventory格式的场景,步骤如下:
- 创建Inventory模板文件
inventory.tpl:
[tomcat] ${public_ip}
- 在
main.tf中添加模板渲染逻辑和生成命令:
data "template_file" "inventory" { template = file("${path.module}/inventory.tpl") vars = { public_ip = aws_instance.my_vm.public_ip } } resource "aws_instance" "my_vm" { # 原有实例配置... provisioner "local-exec" { command = "echo '${data.template_file.inventory.rendered}' > /opt/infrastructure-pipeline/inventory" } }
这种方式可以灵活扩展Inventory内容,比如添加SSH端口、变量参数等。
方法3:实例销毁时清理Inventory(可选)
如果需要在销毁旧实例时清空无效IP,可添加销毁阶段的provisioner:
resource "aws_instance" "my_vm" { # 原有实例配置... provisioner "local-exec" { command = "echo -e '[tomcat]\n${aws_instance.my_vm.public_ip}' > /opt/infrastructure-pipeline/inventory" } provisioner "local-exec" { when = destroy command = "echo '[tomcat]' > /opt/infrastructure-pipeline/inventory" } }
销毁实例后,Inventory会保留分组头但清空IP,避免残留无效地址。
内容的提问来源于stack exchange,提问作者CapMarian
相关产品推荐
相关产品推荐

