题目描述
根据下列要求,在 /home/greg/ansible/roles 中创建名为 apache 的角色:
httpd软件包已安装,设为在系统启动时启用并启动- 防火墙已启用并正在运行,并使用允许访问
Web服务器的规则 - 模板文件
index.html.j2已存在,用于创建具有以下输出的文件/var/www/html/index.html:
Welcome to HOSTNAME on IPADDRESS
其中,HOSTNAME 是受管节点的完全限定域名,IPADDRESS 则是受管节点的 IP 地址。
按照下方所述,创建一个使用此角色的 playbook /home/greg/ansible/newrole.yml: 该 playbook 在 webservers 主机组中的主机上运行。
详细解析
简单地说,本题要求我们做两件事:首先创建一个角色,然后,编写一个 playbook 调用这个角色。
创建 apache 角色
首先,进入到角色目录 /home/greg/ansible/roles, 使用 ansible-galaxy 命令初始化一个名为 apache 的角色:
cd /home/greg/ansible/roles ansible-galaxy init apache
使用上述命令初始化角色成功之后,会返回如下提示信息:
- apache was created successfully
之后,进入到刚才创建的 apache 角色目录 /home/greg/ansible/roles/apache 中,使用 tree 目录可以看到该目录下文件和文件夹的基本结构,如下:
[greg@control apache]$ tree
.
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
角色目录下不同文件夹的作用如下:
- defaults: 角色的默认变量
- files: 包含可以经由此角色部署的文件
- handlers: 包含可以由此角色使用的处理程序
- meta: 角色定义的一些元数据
- tasks: 包含角色要执行的主要任务的列表
- templates: 包含可以经由此角色部署的模板
- tests: 角色的测试文件
- vars: 角色的其他变量
在角色的这些文件夹中,我们需要修改的其实就两个,一个是 tasks 目录下的 playbook main.yml, 我们需要在该 playbook 中写出题目所要求的 apache 角色需要完成的任务;另一个是在 templates 目录下新建一个名为 index.html.j2 的模板文件,该模板文件中的变量,可以在受控端的指定文件中显示相应的内容(对该模板文件的调用需要在 tasks 目录下的 main.yml 中使用 Ansible 的 templates 模块完成)。
接下来开始正式的配置编写。
首先,在 apache 角色的目录下(/home/greg/ansible/roles/apache)编辑 tasks 目录下的 main.yml, 写入如下四段内容:
第一段
使用 yum 模块安装 httpd 软件包:
- name:
yum:
name: httpd
state: present
[1].
yum模块下的name参数用于指定要安装的软件包的名字;[2].
yum模块下的state用于指定软件包的状态,状态包括:installed,present,latest,remove和absent.
第二段
使用 firewalld 模块配置防火墙:
- name:
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
[1].
service: http表示对应的服务是 http, 即 web 服务,注意不要写成 “httpd”;[2].
state: enabled表示防火墙的状态为开启;[3].
permanent: yes表示允许通过;[4].
immediate: yes表示该防火墙规则立即生效。
第三段
使用 template 模块调用和设置模板文件:
- name:
template:
src: index.html.j2
dest: /var/www/html/index.html
owner: apache
group: apache
mode: '0644'
[1].
src参数用于指定控制端模板文件的路径;[2].
dest参数用于指定被控制端文件的路径;[3].
0644代表文件所述用户具有读写权限、所属组的用户和其他用户只具有读权限(读:4,写:2,执行:1)。
由于 apache 角色的模板目录 template 下并没有 index.html.j2 这个文件,因此,我们需要首先创建该并写入如下内容:
Welcome to {{ ansible_hostname }} on {{ ansible_enp1s0.ipv4.address }}
第四段
使用 service 模块重启 httpd 和防火墙,并设置为开机自启动:
重启服务是为了让前面做的配置都生效,因此,调用
service模块这部分要放在整个 playbook 的最后。
- name:
service:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
- httpd
- firewalld
[1].
service模块主要用于管理系统服务,例如启动和停止等;
补充:
有时候,由于被控制端主机上的防火墙服务没有处于开启的状态,那么,在上面的“第二段”配置信息中,使用 immediate: yes 让防火墙规则立即生效的时候就会报错,这个时候,我们可以在 apache 角色 tasks 目录下的 main.yml 文件的开头先调用一次 service 模块启动防火墙,配置如下:
- name:
service:
name: firewalld
state: restarted
enabled: yes
apache 角色 tasks 目录下的 main.yml 文件最终完整的内容如下:
---
# tasks file for apache
- name:
service:
name: firewalld
state: restarted
enabled: yes
- name:
yum:
name: httpd
state: present
- name:
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
- name:
template:
src: index.html.j2
dest: /var/www/html/index.html
owner: apache
group: apache
mode: '0644'
- name:
service:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
- httpd
- firewalld
调用 apache 角色
可以看到,在前面创建和配置 apache 角色的时候,我们并没有指定该角色作用的受控端范围,我们可以新建一个 playbook, 然后在该 playbook 中调用 apache 角色并指定该角色可以作用的受控端的范围,这也正是使用 Ansible 角色的好处之一。
首先,按照题目要求,创建并编辑 playbook:
vim /home/greg/ansible/newrole.yml
之后,在该 playbook 中写入如下内容:
- name:
hosts: webservers
roles:
- apache
接着,运行该 playbook:
ansible-playbook /home/greg/ansible/newrole.yml
最后,可以使用 curl 访问一下属于 websevers 组的 node3 和 node4 这两个受控端主机,如果能返回类似如下信息,则表明配置成功:
[greg@control ansible]$ curl http://node3 Welcome to node3 on 172.25.250.11 [greg@control ansible]$ curl http://node4 Welcome to node4 on 172.25.250.12
为了更接近评分流程,我们可以先重启 node3 和 node4 主机,之后再执行上面的验证操作。