使用Terraform来执行Ansible的playbook
首先
你好,我是SRE工程师hayaosato。
在日常工作中,作为SRE的一部分,我正在推动基础设施即代码(Infrastructure As Code)。
Terraform和Ansible
我计划从基础设施定义到服务器配置一气呵成地执行。具体来说,在使用AWS创建服务器时,我们将使用Terraform定义基础设施,然后使用Ansible进行服务器的中间件安装等操作。此外,我们将在使用Terraform创建服务器后立即执行Ansible作为配置管理工具。以下是代码。
地球塑形
首先,在AWS上创建EC2实例。
这次创建的实例将从最新的Ubuntu18.04 AMI进行创建。
Terraform和提供者的版本如下所示。
Terraform v0.12.16
+ provider.aws v2.38.0
+ provider.local v1.4.0
不可避免的人工智能
要获取最新的AMI ID,您可以按照以下方式进行获取。
data "aws_ami" "latest-ubuntu" {
most_recent = true
owners = ["679593333241"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
您可以使用AWS CLI的ec2 describe-images命令来确认所需获取的AMI,如果您想在其他操作系统上获取相同的最新镜像,则可以参考这个命令。总之,代码文件ec2_images.tf中还包含了获取Centos7和Amazon Linux2最新镜像的方法。
云服务器
接下来是创建EC2实例,如下所示:
resource "aws_instance" "default" {
ami = data.aws_ami.latest-ubuntu.id
key_name = var.key_name
private_ip = var.private_ip
count = 1
security_groups = var.security_groups
subnet_id = var.subnet_id
instance_type = "t3.medium"
tags = {
Name = "terraform-ansible"
}
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ubuntu"
host = var.private_ip
private_key = file("~/.ssh/${var.key_name}.pem")
}
inline = [
"sudo apt install -y python"
]
}
provisioner "local-exec" {
command = "ansible-playbook -i hosts ${var.service_name}.yml"
}
}
希望您能查看官方文档以获取关于上述参数的详细信息。本次执行Ansible是通过provisioner完成的。在terraform中,有多种Provisioning功能可用,包括使用remote-exec和local-exec。
远程执行
为了对EC2资源进行配置,可以使用remote-exec进行远程执行,并在服务器创建后使用SSH等方式连接并执行命令或配置文件。为了执行Ansible,我们安装了Python。
现场执行
本地执行(local-exec)指定了在本地环境中执行Terraform命令的命令,我们将指定它来直接执行Ansible命令。
另外,在使用ansible指令时出现的困扰是指令的指定。
command = "ansible-playbook -i hosts ${var.service_name}.yml --private-key=~/.ssh/${var.key_name}.pem"
以这种方式运行,但偶尔在terraform fmt格式化器中。
command = "ansible-playbook -i hosts ${var.service_name}.yml --private-key = ~/.ssh/${var.key_name}.pem"
由于–private-key指定的前后加入了空格,所以最好在~/.ansible.cfg的private_key_file设置中加以处理。
[defaults]
host_key_checking = False
private_key_file = /path/to/private_key_file
一种选项是:安思富 sī fù)
现在,我认为在这一点上我们已经完成了使用Terraform创建EC2实例的定义。
接下来,我们将创建并运行实际的Ansible配置。
以下是Ansible的版本。
ansible 2.7.15
这次的任务非常简单,只需要使用apt来安装vim即可。
- name: install vim
become: yes
apt:
name: vim
另外,playbook的步骤如下所示。
- hosts: service
remote_user: ubuntu
roles:
- service
本次将省略对于Ansible playbook的说明。
库存文件
在这里,关于清单文件,
hosts设置只需要填写private_ip,但是只要在terraform中管理,只需重用它,
我计划在terraform中创建清单文件。
内容非常简单,如下所示。
在本地创建文件使用的是本地提供者的本地文件。
resource "local_file" "hosts_file" {
content = <<EOF
[${var.service_name}]
${var.private_ip}
EOF
filename = "hosts"
file_permission = "0644"
}
我认为通过使用Terraform进行管理,当需要更改私有IP时,系统可以自动联动,这是很好的。
执行
最后,在运行时设置terraform的var属性。
terraform apply -var-file sample.tfvars
创建一个EC2实例,并在该服务器上执行Ansible的配置已经完成。
最后
這次的結構是為那些想使用Terraform建立實例並直接執行Ansible的人們所設計。
基本上,我認為在Ansible中已經保證了幂等性,所以並不感覺到使用上的必要性,
然而,我還是希望能夠在創建Ansible配置時提供一些可用的功能。
另外,如果对上述结构有任何“这样做更好!”之类的建议,请务必不吝赐教。谢谢!
请参考
-
- 10分で理解するTerraform
-
- Amazon EC2 AMI Locator
-
- Terraform Documentation
- Ansible Documentation