作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
Ansible是一个配置管理工具,执行 playbooks,这是在指定目标服务器上以YAML编写的可定制操作列表。它可以执行所有启动操作,如安装和更新软件,创建和删除用户,并配置系统服务。
Ansible和Terraform不是竞争的解决方案,因为它们解决了基础设施和软件部署的不同阶段。Terraform允许您定义和创建您的系统的基础设施,包括您的应用程序将运行的硬件。反过来,Ansible通过在提供的服务器实例上执行其播放簿来配置和部署软件。在创建后直接提供的Terraform资源上运行Ansible允许您更快地将资源用于您的使用案例。它还允许更轻松的维护和故障排除,因为所有部署的服务器将对它们执行相同的操作。
在本教程中,您将使用Terraform部署Dropplets,然后在创建后立即启动Dropplets使用Ansible。当资源部署时,您将直接从Terraform召唤Ansible。
前提条件
您可以通过DigitalOcean控制面板创建一个DigitalOcean个人访问代码。 您可以在DigitalOcean产品文档中找到指示, How to Create a Personal Access Token。
- Terraform安装在您的本地机器上,并与DigitalOcean提供商一起创建一个项目。 完成DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean如何使用DigitalOcean
<$>[注]
**注:**本教程已被特定的测试与Terraform 1.0.2
<$>
步骤1 - 定义滴滴
在此步骤中,您将定义Dropplets,您将在其后运行一个Ansible播放簿,该书将设置Apache Web 服务器。
假设你是在terraform-ansible
目录中,你创建了作为前提的一部分,你将定义一个Droplet资源,通过指定数
,创建三个副本,并输出他们的IP地址,你将存储定义在名为droplets.tf
的文件中。
1nano droplets.tf
添加以下几行:
1[label ~/terraform-ansible/droplets.tf]
2resource "digitalocean_droplet" "web" {
3 count = 3
4 image = "ubuntu-18-04-x64"
5 name = "web-${count.index}"
6 region = "fra1"
7 size = "s-1vcpu-1gb"
8
9 ssh_keys = [
10 data.digitalocean_ssh_key.terraform.id
11 ]
12}
13
14output "droplet_ip_addresses" {
15 value = {
16 for droplet in digitalocean_droplet.web:
17 droplet.name => droplet.ipv4_address
18 }
19}
在这里,您定义了运行 Ubuntu 18.04 的 Droplet 资源,在fra1
区域内的 CPU 核心上具有 1GB RAM。Terraform 将从您的帐户中提取您在前提条件中定义的 SSH 密钥,并将其添加到提供的 Droplet 中,指定的独特 ID(列表元素)(https://andsky.com/tech/tutorials/how-to-improve-flexibility-using-terraform-variables-dependencies-and-conditionals#data-types-in-hcl)传入ssh_keys
。Terraform 将部署 Droplet 三次,因为设置了计数
参数。 随后的输出块将显示三个 Droplets 的 IP 地址。 loop通过 Droplets 的列表,并在每个例子中将其名称与 IP 地址并附加到结果的地图上。
保存并关闭文件,当你完成。
您现在已经定义了Terraform将部署的Droplets。在下一步,您将编写一个Ansible播放簿,它将在三个部署的Droplets中执行,并部署ApacheWeb服务器。
步骤 2 - 写一个可理解的剧本
您现在将创建一个Ansible播放簿,执行初始服务器设置任务,例如创建新用户和升级已安装的包。您将指示Ansible写 tasks,这是在目标主机上执行的操作单元。
在写本之前,请确保您的公共和私人SSH密钥,这与您的DigitalOcean帐户中的密钥相匹配,在您运行Terraform和Ansible的机器上可用和可访问。
<$>[note] 注: 在 Linux 上,您需要确保私钥文件具有适当的权限。
1chmod 600 your_private_key_location
美元
您已经为私钥定义了变量,因此您只需要为公共密钥位置添加一个变量。
打开provider.tf
进行编辑:
1nano provider.tf
添加下列行:
1[label ~/terraform-ansible/provider.tf]
2terraform {
3 required_providers {
4 digitalocean = {
5 source = "digitalocean/digitalocean"
6 version = "~> 2.0"
7 }
8 }
9}
10
11variable "do_token" {}
12variable "pvt_key" {}
13variable "pub_key" {}
14
15provider "digitalocean" {
16 token = var.do_token
17}
18
19data "digitalocean_ssh_key" "terraform" {
20 name = "terraform"
21}
完成后,保存并关闭文件。
现在定义了pub_key
变量,您将开始写 Ansible 播放簿,将其存储在名为apache-install.yml
的文件中。
1nano apache-install.yml
您将逐步构建播放簿. 首先,您需要定义在哪个主机上播放簿将运行,其名称,以及任务是否应该作为 root运行。
1[label ~/terraform-ansible/apache-install.yml]
2- become: yes
3 hosts: all
4 name: apache-install
通过将成为
设置为是
,您指示Ansible作为超级用户运行命令,并指定所有
为主机
,您允许Ansible在任何特定服务器上运行任务 - 即使是通过命令行传输的任务,就像Terraform一样。
您将添加的第一个任务将创建一个新的非根用户。
1[label ~/terraform-ansible/apache-install.yml]
2 tasks:
3 - name: Add the user 'sammy' and add it to 'sudo'
4 user:
5 name: sammy
6 group: sudo
它将创建一个名为 sammy的用户,并通过将其添加到相应的组授予他们使用sudo
的超级用户访问权限。
下一个任务将为用户添加您的公共 SSH 密钥,因此您可以在稍后连接到它:
1[label ~/terraform-ansible/apache-install.yml]
2 - name: Add SSH key to 'sammy'
3 authorized_key:
4 user: sammy
5 state: present
6 key: "{{ lookup('file', pub_key) }}"
此任务将确保从本地文件中搜索到的公共 SSH 密钥在目标中存在
,您将在下一步提供 Terraform 的pub_key
变量值。
您现在可以通过附加以下任务来命令安装Apache和mod_rewrite
模块:
1[label ~/terraform-ansible/apache-install.yml]
2 - name: Wait for apt to unlock
3 become: yes
4 shell: while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 5; done;
5
6 - name: Install apache2
7 apt:
8 name: apache2
9 update_cache: yes
10 state: latest
11
12 - name: Enable mod_rewrite
13 apache2_module:
14 name: rewrite
15 state: present
16 notify:
17 - Restart apache2
18
19 handlers:
20 - name: Restart apache2
21 service:
22 name: apache2
23 state: restarted
第一个任务将等到使用apt
包管理器的任何之前的包安装完成。第二个任务将运行apt
来安装Apache。然后,第三个任务将确保mod_rewrite
模块存在
。在启用后,您需要确保您重新启动Apache,您无法从任务本身配置。
在这一点上,你的剧本将看起来如下:
1[label ~/terraform-ansible/apache-install.yml]
2- become: yes
3 hosts: all
4 name: apache-install
5 tasks:
6 - name: Add the user 'sammy' and add it to 'sudo'
7 user:
8 name: sammy
9 group: sudo
10
11 - name: Add SSH key to 'sammy'
12 authorized_key:
13 user: sammy
14 state: present
15 key: "{{ lookup('file', pub_key) }}"
16
17 - name: Wait for apt to unlock
18 become: yes
19 shell: while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 5; done;
20
21 - name: Install apache2
22 apt:
23 name: apache2
24 update_cache: yes
25 state: latest
26
27 - name: Enable mod_rewrite
28 apache2_module:
29 name: rewrite
30 state: present
31 notify:
32 - Restart apache2
33
34 handlers:
35 - name: Restart apache2
36 service:
37 name: apache2
38 state: restarted
完成后,请检查所有 YAML 元素的插头是否正确,并匹配上面所示的内容。这就是您在 Ansible 侧面上需要定义的全部,所以保存并关闭播放簿。
步骤 3 – 在部署的滴滴上运行 Ansible
现在你已经定义了Ansible将在目标服务器上执行的操作,你将修改Terraform配置以在Droplet创建时运行它。
Terraform 提供两个执行命令的供应商:本地执行
和远程执行
,分别在本地或远程执行命令(针对目标)。远程执行
需要连接数据,如类型和访问密钥,而本地执行
可以执行Terraform计算机上的所有操作,因此不需要连接信息。
现在,您将向您的 Droplet 添加提供者定义,以便在部署后运行 Ansible。
1nano droplets.tf
添加突出的线条:
1[label ~/terraform-ansible/droplets.tf]
2resource "digitalocean_droplet" "web" {
3 count = 3
4 image = "ubuntu-18-04-x64"
5 name = "web-${count.index}"
6 region = "fra1"
7 size = "s-1vcpu-1gb"
8
9 ssh_keys = [
10 data.digitalocean_ssh_key.terraform.id
11 ]
12
13 provisioner "remote-exec" {
14 inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]
15
16 connection {
17 host = self.ipv4_address
18 type = "ssh"
19 user = "root"
20 private_key = file(var.pvt_key)
21 }
22 }
23
24 provisioner "local-exec" {
25 command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u root -i '${self.ipv4_address},' --private-key ${var.pvt_key} -e 'pub_key=${var.pub_key}' apache-install.yml"
26 }
27}
28
29output "droplet_ip_addresses" {
30 value = {
31 for droplet in digitalocean_droplet.web:
32 droplet.name => droplet.ipv4_address
33 }
34}
与Terraform一样,Ansible在本地运行,并通过SSH连接到目标服务器。要运行它,您在Droplet定义中定义了一个本地执行
提供器,它运行了ansible-playbook
命令。这会传输到用户名(root),当前Droplet的IP(用${self.ipv4_address
)恢复,SSH的公共和私人密钥,并指定要运行的播放簿文件(apache-install.yml
).通过将ANSIBLE_HOST_KEY_CHECKING
环境变量设置为False
,您会忽略检查服务器是否已连接到。
如前所述,本地exec
提供器在不等待Droplet的可用性下运行,因此播放本的执行可能先于Droplet的实际可用性。 为了修复此问题,你将远程exec
提供器定义为包含在目标服务器上执行的命令。 为了远程exec
执行,目标服务器必须可用。 由于远程exec
在本地exec
之前运行,服务器将在呼吁 Ansible时完全初始化。
完成更改后,保存并关闭文件。
然后,运行下面的命令来部署 Droplets. 请记住将private_key_location
和public_key_location
替换为您的私钥和公共钥匙的位置:
1terraform apply -var "do_token=${DO_PAT}" -var "pvt_key=private_key_location" -var "pub_key=public_key_location"
您的 Droplets 将提供,然后将与每一个建立连接。接下来,远程执行器将执行并安装 Python3:
1[secondary_label Output]
2...
3digitalocean_droplet.web[1] (remote-exec): Connecting to remote host via SSH...
4digitalocean_droplet.web[1] (remote-exec): Host: ...
5digitalocean_droplet.web[1] (remote-exec): User: root
6digitalocean_droplet.web[1] (remote-exec): Password: false
7digitalocean_droplet.web[1] (remote-exec): Private key: true
8digitalocean_droplet.web[1] (remote-exec): Certificate: false
9digitalocean_droplet.web[1] (remote-exec): SSH Agent: false
10digitalocean_droplet.web[1] (remote-exec): Checking Host Key: false
11digitalocean_droplet.web[1] (remote-exec): Connected!
12...
之后,Terraform将为每一个Dropplets运行本地执行
程序,该程序执行 Ansible。
1[secondary_label Output]
2...
3digitalocean_droplet.web[2] (local-exec): Executing: ["/bin/sh" "-c" "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u root -i 'ip_address,' --private-key private_key_location -e 'pub_key=public_key_location' apache-install.yml"]
4
5digitalocean_droplet.web[2] (local-exec): PLAY [apache-install] **********************************************************
6
7digitalocean_droplet.web[2] (local-exec): TASK [Gathering Facts] *********************************************************
8digitalocean_droplet.web[2] (local-exec): ok: [ip_address]
9
10digitalocean_droplet.web[2] (local-exec): TASK [Add the user 'sammy' and add it to 'sudo'] *******************************
11digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
12
13digitalocean_droplet.web[2] (local-exec): TASK [Add SSH key to 'sammy''] *******************************
14digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
15
16digitalocean_droplet.web[2] (local-exec): TASK [Update all packages] *****************************************************
17digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
18
19digitalocean_droplet.web[2] (local-exec): TASK [Install apache2] *********************************************************
20digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
21
22digitalocean_droplet.web[2] (local-exec): TASK [Enable mod_rewrite] ******************************************************
23digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
24
25digitalocean_droplet.web[2] (local-exec): RUNNING HANDLER [Restart apache2] **********************************************
26digitalocean_droplet.web[2] (local-exec): changed: [ip_address]
27
28digitalocean_droplet.web[2] (local-exec): PLAY RECAP *********************************************************************
29digitalocean_droplet.web[2] (local-exec): [ip_address] : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
30
31...
在输出结束时,您将收到三个Dropplets及其IP地址的列表:
1[secondary_label Output]
2droplet_ip_addresses = {
3 "web-0" = "..."
4 "web-1" = "..."
5 "web-2" = "..."
6}
您现在可以导航到您的浏览器中的IP地址之一,您将到达默认的Apache欢迎页面,表示成功安装Web服务器。
这意味着Terraform提供您的服务器和您的Ansible播放簿在其上成功执行。
要检查提供的 Droplets 上 SSH 密钥是否正确添加到 sammy,请使用以下命令连接到其中一个:
1ssh -i private_key_location sammy@droplet_ip_address
请记住输入私钥位置和提供的 Droplets 中的一个 IP 地址,您可以在您的 Terraform 输出中找到。
结果将类似于以下:
1[secondary_label Output]
2Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-121-generic x86_64)
3
4 * Documentation: https://help.ubuntu.com
5 * Management: https://landscape.canonical.com
6 * Support: https://ubuntu.com/advantage
7
8 System information as of ...
9
10 System load: 0.0 Processes: 88
11 Usage of /: 6.4% of 24.06GB Users logged in: 0
12 Memory usage: 20% IP address for eth0: ip_address
13 Swap usage: 0% IP address for eth1: ip_address
14
150 packages can be updated.
160 updates are security updates.
17
18New release '20.04.1 LTS' available.
19Run 'do-release-upgrade' to upgrade to it.
20
21*** System restart required ***
22Last login: ...
23...
您已成功连接到目标并为 sammy 用户获得壳存取,这确认 SSH 密钥对该用户进行了正确配置。
您可以通过运行以下命令来摧毁部署的 Droplets,当被提示时输入是
:
1terraform destroy -var "do_token=${DO_PAT}" -var "pvt_key=private_key_location" -var "pub_key=public_key_location"
在此步骤中,您已在您的 Droplet 定义中添加了 Ansible 播放本执行程序作为一个本地执行程序
提供程序. 为了确保服务器可供连接,您已包括了远程执行程序
提供程序,它可以用于安装python3
的前提条件,然后 Ansible 将运行。
结论
Terraform 和 Ansible 一起构成一个灵活的工作流程,可以将服务器与所需的软件和硬件配置进行旋转,直接运行 Ansible 作为 Terraform 部署流程的一部分,可让您更快地为您的开发工作和应用程序启动和启动服务器。
本教程是《如何使用Terraform管理基础设施》系列的一部分,该系列涵盖了许多Terraform主题,从首次安装Terraform到管理复杂项目。
您还可以在我们的 Ansible 主题页面上找到其他 Ansible 内容资源。