公司内部紧急会议话题:在两周内完全掌握Ansible入门概述
对于Ansible我完全不懂。
首先
因为有机会在工作中使用Ansible来自动化服务器的构建,我从头开始重新学习了它,所以总结了一些关于Playbook、Inventory以及目录结构等方面的写作方法。
我没有详细说明模块的细节。
這並不是正確的答案,而是依照這樣的方式製作,然後這樣運作的內容進行了有序的解釋。
环境
-
- CentOS 7.6 1810
1台でもできるけど、Ansible実行用と処理対象用の複数台あるとわかりやすい
Ansible 2.6 (最新は2.8)
参考书籍
- Ansible実践ガイド第2版 impress top gearシリーズ Kindle版
安装和配置Ansible
虚拟机
如果是为了验证,可以使用VirtualBox和Vagrant来构建基于Ansible验证环境的Vagrant,通过设置多个虚拟机、虚拟机之间的SSH公钥认证和共享文件夹,可以简单地创建所需的最低限度环境。
安装yum
在没有进行任何特别设置的情况下,在CentOS 7.6上执行yum install ansible命令,会安装版本为2.4的Ansible。
通过安装centos-release-ansible26软件包,可以添加针对2.6版本的存储库,然后使用yum来安装Ansible 2.6,因此选择使用这种方式进行安装。
[root@ansible-controller ~]# yum install centos-release-ansible26
然后就会生成这样的文件:/etc/yum.repos.d/CentOS-ANSIBLE.repo
使用yum install ansible命令后,将会安装2.6版本的ansible。
[root@ansible-controller ~]# yum install ansible
[vagrant@ansible-controller ~]$ ansible --version
ansible 2.6.14
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
[vagrant@ansible-controller ~]$
Ansible的安装只需要在执行Ansible的服务器上进行,不需要任何处理目标服务器(只要SSH可用)。
对目标节点的SSH访问权限
使用Ansible进行远程服务器的环境配置,需要确保远程服务器可以进行无密码的SSH公钥验证(尽管有些设置不需要,但为了简化ansible和ansible-playbook的执行过程,省略密码可以使操作更简洁)。
鍵設定的概要是使用适用于Ansible验证环境的Vagrant创建虚拟机 – 包括多个虚拟机、虚拟机之间的SSH公钥身份验证设置和共享文件夹。
使用”sudo”命令
当在远程服务器上执行具有root权限的操作时,需要确保sudo可以无需密码就能执行。若是在使用Vagrant创建的虚拟机中使用vagrant用户,则应该无需这一步骤。
如果将构成图示出来的话,会是这样的感觉。
Ansible配置文件
Ansible的配置文件
[defaults]
host_key_checking = False
当首次进行SSH连接时,若在known_hosts中没有SSH服务器的配置,会被询问是否连接到该主机,即使之前没有连接过。但如果事先设置这些配置,就可以被省略。
另外还有日志输出配置和并发处理数量等。
读取设置文件的优先级如下所示。
-
- 通过环境变量ANSIBLE_CONFIG指定的路径文件
-
- 当前目录的ansible.cfg
执行用户的~/.ansible.cfg
执行主机的/etc/ansible/ansible.cfg
Ansible配置设置 — Ansible文档
战略手册和库存。
战略规划书
Playbook定义了“做什么”的内容。采用YAML格式。
许多Ansible模块可以组合使用,用于进行软件包安装、配置文件更改等操作。
库存
库存定义了“处理对象是什么”。类似于Windows的ini格式。
可以对目标主机进行分组,或者为每个组定义专有的设置变量。
也可以使用YAML格式在外部文件中进行定义。
最小的构建档案和清单。
虽然称之为最小,但目标有两个,但那就暂且放在一边。
[ansible_practice]
192.168.244.120
192.168.244.121
被pip的VM被记录在库存中。
[ansible_practice]是“组名”,在Playbook中,我们将描述在这个组名中执行任务的目标。
在组名的描述之后,是目标主机的处理。
---
- hosts: ansible_practice
tasks:
- ping:
要执行 Ansible Playbook,需要使用 ansible-playbook 命令运行编写在 Playbook 中的任务。
必需参数是 Playbook 文件。可以使用 -i Inventory 文件名 来指定 Inventory 文件(如果未指定,默认使用 /etc/ansible/hosts)。
[vagrant@ansible-controller practice]$ ls
inventory.ini inventory.yml playbook.yml
[vagrant@ansible-controller practice]$ ansible-playbook -i inventory.ini playbook.yml
PLAY [ansible_practice] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.244.121]
ok: [192.168.244.120]
TASK [ping] ********************************************************************
ok: [192.168.244.120]
ok: [192.168.244.121]
PLAY RECAP *********************************************************************
192.168.244.120 : ok=2 changed=0 unreachable=0 failed=0
192.168.244.121 : ok=2 changed=0 unreachable=0 failed=0
[vagrant@ansible-controller practice]$
实行结果简要总结将显示在PLAY RECAP部分。
指定主机名
用主机名指定存货
[ansible_practice]
ansible-controller
ansible-node01
无论是使用DNS还是/etc/hosts进行名称解析都可以,但如果无法解析名称,当然会出现错误……应该是这样的,但最近的CentOS还是Vagrant环境是这样的,仅仅使用主机名时会添加.localhost(这是/etc/resolv.conf中search的设置),而且在同一网段内还有一个神秘的DNS服务器运行,并且返回127.0.0.1,所以即使采用了意外的设置,它仍然可以运行一次。
虽然如此,在解释时很容易偏离主题,但是只需要在Inventory中添加主机变量(host variable),也就是”ansible_host”,将IP地址写入到此行为清单参数(behavioral inventory parameters)中即可。
[ansible_practice]
ansible-controller ansible_host=192.168.244.120
ansible-node01 ansible_host=192.168.244.121
那么,在执行Ansible时,将会将”ansible-node01″的地址处理为”192.168.244.121″。
[vagrant@ansible-controller practice]$ ansible-playbook -i inventory.ini playbook.yml
PLAY [ansible_practice] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [ansible-node01]
ok: [ansible-controller]
TASK [ping] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
PLAY RECAP *********************************************************************
ansible-controller : ok=2 changed=0 unreachable=0 failed=0
ansible-node01 : ok=2 changed=0 unreachable=0 failed=0
[vagrant@ansible-controller practice]$
增加任务
我尝试在这个playbook.yml中添加任务(操作)。
创建目录
尝试使用文件模块创建一个目录。
---
- hosts: ansible_practice
tasks:
- ping:
- file:
path: /tmp/ansible/practice
state: directory
owner: vagrant
mode: 0755
进行
[vagrant@ansible-controller practice]$ ansible-playbook -i inventory.ini playbook.yml
PLAY [ansible_practice] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [ansible-node01]
ok: [ansible-controller]
TASK [ping] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [file] ********************************************************************
changed: [ansible-controller]
changed: [ansible-node01]
PLAY RECAP *********************************************************************
ansible-controller : ok=3 changed=1 unreachable=0 failed=0
ansible-node01 : ok=3 changed=1 unreachable=0 failed=0
[vagrant@ansible-controller practice]$
结果 (jié guǒ)
[vagrant@ansible-controller practice]$ ls -al /tmp/ansible/
total 4
drwxr-xr-x. 3 vagrant vagrant 22 Jul 14 00:45 .
drwxrwxrwt. 10 root root 4096 Jul 14 00:48 ..
drwxr-xr-x. 2 vagrant vagrant 6 Jul 14 00:45 practice
[vagrant@ansible-controller practice]$ ssh 192.168.244.121 ls -al /tmp/ansible/
total 4
drwxr-xr-x. 3 vagrant vagrant 22 Jul 14 00:45 .
drwxrwxrwt. 10 root root 4096 Jul 14 00:45 ..
drwxr-xr-x. 2 vagrant vagrant 6 Jul 14 00:45 practice
使用yum进行安装,并获取root权限。
从这里开始,尝试使用yum安装Ruby软件包。
---
# - hosts: ansible_host=192.168.244.121
- hosts: ansible_practice
tasks:
- ping:
- file:
path: /tmp/ansible/practice
state: directory
owner: vagrant
mode: 0755
- yum:
name: ruby
state: present
如果你是聪明的人,我相信你会注意到的,…
[vagrant@ansible-controller practice]$ ansible-playbook -i inventory.ini playbo
ok.yml
PLAY [ansible_practice] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [ansible-node01]
ok: [ansible-controller]
TASK [ping] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [file] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [yum] *********************************************************************
fatal: [ansible-node01]: FAILED! => {"changed": false, "msg": "You need to be root to perform this command.\n", "rc": 1, "results": ["Loaded plugins: fastestmirror\n"]}
fatal: [ansible-controller]: FAILED! => {"changed": false, "msg": "You need to be root to perform this command.\n", "rc": 1, "results": ["Loaded plugins: fastestmirror\n"]}
to retry, use: --limit @/ansible/practice/playbook.retry
PLAY RECAP *********************************************************************
ansible-controller : ok=3 changed=0 unreachable=0 failed=1
ansible-node01 : ok=3 changed=0 unreachable=0 failed=1
[vagrant@ansible-controller practice]$
由于没有根权限,操作失败。
另外,前一步骤的文件创建已经是”ok”状态(因为已经处于该状态,所以没有进行其他处理)。具备冪等性。
要以root身份运行,需要指定become(默认为false)。
将become设为true,将默认以root身份运行。
要以become以root权限运行,必须在主机上配置sudo su -可以无需密码以root身份启动shell。
---
- hosts: ansible_practice
become: true
tasks:
- ping:
- file:
path: /tmp/ansible/practice
state: directory
owner: vagrant
mode: 0755
- yum:
name: ruby
state: present
[vagrant@ansible-controller practice]$ ansible-playbook -i inventory.ini playbook.yml
PLAY [ansible_practice] ********************************************************
TASK [Gathering Facts] *********************************************************
ok: [ansible-node01]
ok: [ansible-controller]
TASK [ping] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [file] ********************************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [yum] *********************************************************************
changed: [ansible-node01]
changed: [ansible-controller]
PLAY RECAP *********************************************************************
ansible-controller : ok=4 changed=1 unreachable=0 failed=0
ansible-node01 : ok=4 changed=1 unreachable=0 failed=0
[vagrant@ansible-controller practice]$
已安装了Ruby。
[vagrant@ansible-controller practice]$ ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
[vagrant@ansible-controller practice]$ ssh 192.168.244.121 ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
[vagrant@ansible-controller practice]$
通过名字来说明任务
在执行ansible-playbook时,只会输出所使用的模块名称,例如file和yum,导致很难明确知道具体执行了什么。为了方便在执行时进行确认,可以通过在任务的name中简洁地描述任务的内容。
- name: create directory
file:
path: /tmp/ansible/practice
state: directory
owner: vagrant
mode: 0755
- name: install ruby package
yum:
name: ruby
state: present
发挥力量
TASK [create directory] ********************************************************
ok: [ansible-controller]
ok: [ansible-node01]
TASK [install ruby package] ****************************************************
ok: [ansible-node01]
ok: [ansible-controller]
PLAY RECAP *********************************************************************
ansible-controller : ok=4 changed=0 unreachable=0 failed=0
ansible-node01 : ok=4 changed=0 unreachable=0 failed=0
安装Apache并更改端口号以及启用服务。
相当常见的一些小例子
- hosts: ansible_practice
become: true
tasks:
- name: install httpd server
yum:
name: httpd
state: present
- name: configure httpd server
replace:
path: /etc/httpd/conf/httpd.conf
regexp: ^#?Listen 80$
replace: Listen 8080
- name: enable httpd service
systemd:
name: httpd
state: restarted
enabled: yes
使用正则表达式进行文件编辑时的注意事项
- name: configure httpd server
replace:
path: /etc/httpd/conf/httpd.conf
regexp: Listen 80
replace: Listen 8080
如果写成这样的话…
第一次执行
- Listen 80
+ Listen 8080
在更新并执行两次后,regexp:Listen 80仍然与此行匹配,所以这次是指
- Listen 8080
+ Listen 808080
执行时需要注意排除重复的情况。在进行重复执行时,需要注意排除的对象。 (例如,在这个例子中,可以使用`^ $`来明确表示行首和行尾等)。
设置Inventory文件的配置
团体
到目前为止,我们只使用了[ansible_practice]组,但是当然可以定义多个组,并且可以将某个节点(处理目标主机)设置为多个组。
[ansible_practice]
ansible-controller ansible_host=192.168.244.120
ansible-node01 ansible_host=192.168.244.121
[php-server]
ansible-node01
如果这样写,[ansible_practice]组将包括ansible-controller和ansible-node01,而[php-server]组只包含ansible-node01。
ansible-node01同时包含在[ansible_practice]和[php-server]两个群组中。
简而言之,如果在Playbook中将hosts指定为ansible_practice,那么该Playbook将在ansible-controller和ansible-node01上执行;而如果指定为php-server,那么该Playbook将只在ansible-node01上执行。
顺便说一下,使用ansible_host进行IP地址指定似乎只需要在第一次使用即可。
库存变量
在使用Ansible进行处理的内容基本上都会写到Playbook中,但是针对不同的环境会创建多个Inventory文件,因为不同的环境有不同的设置……比如在环境A中,web服务器使用8080/TCP运行,而在环境B中使用8888/TCP运行,等等……虽然可以为每个环境准备一份Playbook,但任务除了端口号之外的内容是相同的,所以如果能够将端口号作为变量写入Inventory文件中就很方便了吧。(对吧?)
Playbook是共通的,在Inventory中,变量的定义位于以下形式的[组名:vars]之后。
Playbook是共通的,在Inventory中,变量定义应位于以下[组名:vars]之后。
[ansible_practice]
ansible-controller ansible_host=192.168.244.120
ansible-node01 ansible_host=192.168.244.121
[ansible_practice:vars]
http_port=8080
[ansible_practice]
ansible-controller ansible_host=172.16.10.10
ansible-node01 ansible_host=172.16.10.11
[ansible_practice:vars]
http_port=8888
通过在[ansible_practice:vars]部分进行配置,您可以在处理组[ansible_practice]时,使用变量名http_port来引用值。
根据此变量的引用,我们可以修改前面提到的处理web服务器端口号重写的Playbook,以实现与环境无关的描述,大概可以这样做。
- name: configure httpd server
replace:
path: /etc/httpd/conf/httpd.conf
regexp: ^#?Listen [0-9]+$
replace: Listen {{ http_port }}
现在,通过将之前在Playbook中硬编码的配置值提取到Inventory变量中,我们可以根据不同的环境执行ansible-playbook,对于环境A,使用inventory-a.ini文件,对于环境B,使用inventory-b.ini文件,从而构建各自的环境。
顺便说一下,不写在组名中,而写在[all:vars]中,也可以定义与组无关的可引用值。也就是所谓的全局变量。
将 Inventory 变量外部化为文件。
由于可以将Inventory变量定义为key=value形式的ini文件,所以对于单个设置是没有问题的。但是无法表达列表(数组)或映射(哈希・字典)格式。
例如,用户可以列举 “/etc/hosts” 的主机和IP地址清单(数量不确定),或者列举通过 iptables 允许的目标端口号清单,还可以列举在 DHCP 服务器上为特定客户端设置固定地址时的MAC地址和IP地址对。
在这种情况下,您可以在Playbook或Inventory文件的相同目录下创建group_vars/组名.yml文件,并在其中以YAML格式编写任意设置,从而使Playbook可以引用该文件。
使用`with_items`和YAML格式的Inventory变量进行循环处理。
[smbserver]
ansible-node01
在group_vars目录下创建与Inventory文件中的组名同名的YAML文件。
---
shared_folder:
- name: logs
comment: log directory
path: /opt/logs
create_mask: "0644"
directory_mask: "0755"
writable: "no"
browseable: "no"
- name: share
comment: shared directory
path: /share
create_mask: "0664"
directory_mask: "0775"
writable: "yes"
browseable: "yes"
在有此Inventory文件的情况下,定义Playbook如下。
- hosts: smbserver
become: true
tasks:
- name: install samba server
yum:
name: samba
state: present
- name: configure samba server
blockinfile:
path: /etc/samba/smb.conf
marker: "# {mark} {{ item.name }} configuration by ansible"
block: |
[{{ item.name }}]
comment = {{ item.comment }}
path = {{ item.path }}
create mask = {{ item.create_mask }}
directory mask = {{ item.directory_mask }}
writable = {{ item.writable }}
browseable = {{ item.browseable }}
with_items: '{{ shared_folder }}'
当使用这个ansible-playbook进行执行时,/etc/samba/smb.conf的相关部分如下所示。
# BEGIN logs configuration by ansible
[logs]
comment = log directory
path = /opt/logs
create mask = 0660
directory mask = 0770
writable = no
browseable = no
# END logs configuration by ansible
# BEGIN share configuration by ansible
[share]
comment = shared directory
path = /share
create mask = 0644
directory mask = 0755
writable = yes
browseable = yes
# END share configuration by ansible
通过在任务中使用with_items来指定一个数组形式的变量,可以在循环内部(在with_items上方的代码块中)使用{{ item }}作为变量名进行引用。
在编程语言中,可以类比为 foreach(var item in shared_folder) { … },它们的功能是相同的。(在循环中,变量名item是固定的)
在上述的配置中,shared_folder的元素是以地图形式的,如name、comment等,因此可以使用{{ item.comment }}等来引用每个设置值。
有关blockinfil模块,请参考文档。
使用with_items的循环不仅可以引用在Inventory变量中定义的数组,还可以在现场定义的列表进行循环处理。语法如下所示。
with_items:
- foo
- bar
- baz
在循环的块内,将{{ item }}替换为foo、bar、baz,每次循环都会产生不同的结果。
※ 自Ansible 2.5版本之后,通过with_X(如with_items)循环处理已被替换为loop。
将任务分割为角色
在此之前的例子中,Playbook的内容如下所示。
-
- ping
-
- ディレクトリ作成
-
- rubyのyumインストール
-
- httpdのyumインストール
-
- httpd.confの編集
-
- httpdサービスの有効化
-
- sambaのyumインストール
- smb.confの設定
这些内容都被写在了playbook.yml文件中,类似于编程中的main()函数中包含了所有的处理过程,这种状态非常不好维护和阅读(特别是考虑到未来可能会增加更多的处理内容)。
在编程中,我们可以为每个处理单元创建函数,并从main()函数中调用它们。同样地,Playbook也可以使用Role来实现同样的目的。
将main()函数或其他函数化只是作者个人的感觉和比喻。
表达成图像的话就是如下这种感觉
创建角色
试着将httpd的安装、配置和服务设置分离为角色。
在Playbook中将任务创建为角色的文件是roles/角色名/tasks/main.yml。
---
- name: install httpd server
yum:
name: httpd
state: present
- name: configure httpd server
replace:
path: /etc/httpd/conf/httpd.conf
regexp: ^#?Listen [0-9]+$
replace: Listen {{ http_port }}
- name: enable httpd service
systemd:
name: httpd
state: restarted
enabled: yes
同样的,安装Samba。
---
- name: install samba server
yum:
name: samba
state: present
- name: configure samba server
blockinfile:
path: /etc/samba/smb.conf
marker: "# {mark} {{ item.name }} configuration by ansible"
block: |
[{{ item.name }}]
comment = {{ item.comment }}
path = {{ item.path }}
create mask = {{ item.create_mask }}
directory mask = {{ item.directory_mask }}
writable = {{ item.writable }}
browseable = {{ item.browseable }}
with_items: '{{ shared_folder }}'
- name: enable samba service
systemd:
name: smb
state: restarted
enabled: yes
角色的引用(调用)
从Playbook中调用所创建的Role。
就像函数调用一样。
- hosts: wwwserver
become: true
roles:
- install_httpd
- hosts: smbserver
become: true
roles:
- install_samba
就像函数调用一样,当然也可以从多个地方调用。
例如,在上述情况中,将web服务器和samba服务器分别放在不同的组中,但即使在”为了热备份准备一台服务器,并在一台服务器上运行web/samba”的情况下,也可以使用相同的角色,只需更改清单和Playbook。
- hosts: wwwserver
become: true
roles:
- install_httpd
- hosts: smbserver
become: true
roles:
- install_samba
- hosts: standby
become: true
roles:
- install_httpd
- install_samba
可以按照以下方式进行。
在这种情况下,通过将web服务器的端口号设置为group_vars/wwwserver.yml中的http_port: 8080,并将group_vars/standby中的http_port: 28080来修改备用服务器的配置。
模块
在Ansible中,已经默认提供了各种模块。
无论是操作系统的配置更改、软件包管理还是更新配置文件等,通常都可以通过组合模块来实现。应该是这样的。
简要解释一下
贝壳
执行shell命令于目标主机 – Ansible文档
执行Linux命令。然而,它不能保证幂等性(不会检查执行是否是必要的),因此在执行前需要添加检查任务或进行适当调整。
首先,我们可以尝试寻找一个可以实现所需命令的模块。作为寻找模块的方法,从类别页面开始搜索也是一个不错的选择。
在这个搜索框中输入命令(如果没有正确匹配的话,可以使用相关关键词),然后进行搜索,如果有的话会出现合适的模块。
如果有点击,可以查看模块说明页面的「参数」和「示例」,大概就能解决(很抱歉,只是个大概)。
模板
使用Python的模板引擎Jinja2,能够将模板文件通过Inventory变量等定义的变量进行替换,并将文件复制到目标服务器中。
与replace和lineinfile等文件更改处理不同,不需要过多考虑幂等性,因此简化了操作。
如果设置文件的修改部分大部分不是简单的键值对形式,使用模板可能更容易。
作为例子,DHCP服务器(dhcp-4.2.5-68.el7.centos.1.x86_64)的设定。
option domain-name "ansible.practice.localhost";
option domain-name-servers 192.168.244.120;
default-lease-time 3600;
max-lease-time 86400;
ddns-update-style none;
log-facility local7;
subnet 192.168.244.0 netmask 255.255.255.0 {
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.244.255;
option routers 192.168.244.1;
range 192.168.244.60 192.168.244.99;
}
host client01 {
hardware ethernet 00:00:5e:00:53:01;
fixed-address 192.168.244.31;
}
host client02 {
hardware ethernet 00:00:5e:00:53:02;
fixed-address 192.168.244.32;
}
如果想创建这样一个文件的话…
option domain-name "{{ domain_name }}";
option domain-name-servers {{ dns }};
default-lease-time 3600;
max-lease-time 86400;
ddns-update-style none;
log-facility local7;
subnet {{ network_addr }} netmask {{ subnet_mask }} {
option subnet-mask {{ subnet_mask }};
option broadcast-address {{ broadcast }};
option routers {{ gateway }};
range {{ range_begin }} {{ range_end }};
}
{% for host in hosts_conf %}
host {{ host.name }} {
hardware ethernet {{ host.hwaddr }};
fixed-address {{ host.fixedaddr }};
}
{% endfor %}
将模板文件放置在tasks目录的同一级别下创建一个templates目录,并在其中以.j2扩展名进行配置。
---
- name: install dhcp server
yum:
name: dhcp
state: present
- name: configure dhcp server
template:
src: dhcpd.conf.j2
dest: /etc/dhcp/dhcpd.conf
owner: root
group: root
mode: "0644"
在`role`中使用`template`模块来指定模板文件(.j2),通过`src`参数指定文件路径。如果不指定路径,将默认使用`templates`目录作为基准。
---
domain_name: ansible.practice.localhost
dns: "192.168.244.120"
network_addr: "192.168.244.0"
subnet_mask: "255.255.255.0"
broadcast: "192.168.244.255"
gateway: "192.168.244.1"
range_begin: "192.168.244.60"
range_end: "192.168.244.99"
hosts_conf:
- name: client01
hwaddr: 00:00:5e:00:53:01
fixedaddr: "192.168.244.31"
- name: client02
hwaddr: 00:00:5e:00:53:02
fixedaddr: "192.168.244.32"
下面是作为模板文件参数的Inventory变量的示例。
通过这个,模板文件中的{{ network_addr }}的部分将被替换为192.168.244.0。
在模板中使用for语法可以对所定义的hosts_conf列表进行循环处理。
{% for host in hosts_conf %}
{% endfor %}
与with_items固定项相比,使用模板可以自由设置循环内的变量(例如上面的例子中的host)。
整个文件架构
.
├── ansible.cfg
├── group_vars
│ ├── dhcpserver.yml
│ ├── smbserver.yml
│ └── wwwserver.yml
├── inventory.ini
├── playbook.yml
└── roles
├── install_dhcpd
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ └── dhcpd.conf.j2
├── install_httpd
│ └── tasks
│ └── main.yml
└── install_samba
└── tasks
└── main.yml