Ale*_*hen 12 idempotent ansible terraform
我注意到terraform只会在资源上运行一次"file","remote-exec"或"local-exec".一旦资源被配置,如果"remote-exec"中的命令被更改或者来自供应者"file"的文件被更改,则terraform将不会对实例进行任何更改.那么每次运行terraform时,如何让terraform运行供应商"file","remote-exec"或"local-exec"?
更多细节:
由于"remote-exec"错误导致terraform停止(通常是因为我在编写脚本时输入了错误的命令),我经常部署资源.在此之后再次运行terraform将导致先前创建的资源被破坏并强制terraform从头开始创建新资源.这也是我可以在资源上运行两次"remote-exec"的唯一方法......从头开始创建它.
对于terraform来说,这确实是一个缺点,而不是ansible,它可以做与terraform完全相同的工作,除了它完全是幂等的.当使用Ansible执行诸如"ec2","shell"和"copy"之类的任务时,我可以完成与terraform相同的任务,只有每个任务都是幂等的.Ansible会自动识别何时不需要进行更改,它会在何处进行更改,因此可以自动识别失败的ansible-playbook停止的位置而不会破坏所有内容并从头开始.Terraform缺乏此功能.
这里是一个简单的terraform资源块,供ec2实例使用"remote-exec"和"file"配置器:
resource "aws_instance" "test" {
count = ${var.amt}
ami = "ami-2d39803a"
instance_type = "t2.micro"
key_name = "ansible_aws"
tags {
name = "test${count.index}"
}
#creates ssh connection to consul servers
connection {
user = "ubuntu"
private_key="${file("/home/ubuntu/.ssh/id_rsa")}"
agent = true
timeout = "3m"
}
provisioner "remote-exec" {
inline = [<<EOF
sudo apt-get update
sudo apt-get install curl unzip
echo hi
EOF
]
}
#copying a file over
provisioner "file" {
source = "scripts/test.txt"
destination = "/path/to/file/test.txt"
}
}
Run Code Online (Sandbox Code Playgroud)
小智 24
在我的搜索中遇到了这个帖子并最终找到了一个解决方案:
resource "null_resource" "ansible" {
triggers {
key = "${uuid()}"
}
provisioner "local-exec" {
command = "ansible-playbook -i /usr/local/bin/terraform-inventory -u ubuntu playbook.yml --private-key=/home/user/.ssh/aws_user.pem -u ubuntu"
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用每个terraform运行独有的uuid()来触发空资源或配置器.
在对供应Terraform文档明确表示,它认为使用供应方的基本引导作为曾经唯一的任务,它不应该被用来作为一个适当的配置管理工具,如Ansible更换:
配置程序仅在创建资源时运行.它们不是配置管理的替代品,也不是更改已经运行的服务器的软件,而只是作为引导服务器的一种方式.对于配置管理,您应该使用Terraform配置来调用真实的配置管理解决方案.
和
如果资源成功创建但在提供期间失败,则Terraform将发生错误并将资源标记为"受污染".被物理创建的资源已被物理创建,但由于配置失败,因此无法认为是安全的.
当您生成下一个执行计划时,Terraform将删除任何受污染的资源并创建新资源,尝试再次进行配置.它不会尝试在同一资源上重新启动配置,因为它不能保证安全.
当故障发生时,Terraform不会在应用期间自动回滚并销毁资源,因为这会违反执行计划:执行计划会说创建资源,但不会说它将被删除.但是,如果您使用受污染的资源创建执行计划,该计划将明确指出该资源将被销毁,因为它已被污染.
配置对于能够引导实例很重要.另外提醒一下,它不是配置管理的替代品.它只是为了引导机器.如果使用配置管理,则应使用配置作为引导配置管理实用程序的方法.
将配置程序视为类似于EC2用户数据脚本,因为它仅在创建时运行一次,如果失败,则需要销毁该实例并再次尝试.
这样做的好处是,Terraform不需要知道如何在操作系统上使更改具有幂等性,因为Terraform的工作级别高于实例本身,而且更多的是配置整个数据中心.
如果您需要比此更多的灵活性,那么考虑使用Terraform调用配置管理系统来正确配置实例(如果失败,则允许重试,与Terraform配置阶段分离)或使用诸如Jenkins之类的编排工具包装Terraform和替代配置管理工具,如Ansible.
另一个选择是更多地沿着不可变基础设施的路线,并使用Packer使用Ansible或其他工具创建AMI,然后只需使用Terraform按原样部署AMI,而无需进一步配置实例.