RHCE8 资料整理
第 34 章 角色
- 角色(Role)是什么?
从表面上看,它就是一个目录。目录的名字也就是role的名字,例如叫做webservers。进到这个role名字的目录里,会发现好多子目录。
使用时,每个目录必须包含一个main.yml文件,这个文件应该包含如下目录名称对应的内容:
名称 | 说明 |
---|---|
tasks | 存放 task 任务,包含角色要执行的任务的主要列表 ,tasks/main.yml -角色执行的主要任务列表,此文件可以使用 include包含其他的位于此目录中的tasks文件; |
handlers | 存放 handlers 任务,包含处理程序,此角色甚至该角色之外的任何地方都可以使用这些处理程序 |
files | 存放 task 中引用的文件,包含可以通过此角色部署的文件 |
templages | 存放 task 中引用的模板 |
meta | 存在 role 的依赖role(这个role 执行前,要先执行那个role) |
vars | 存放 role 的其他变量 |
defaults | 存在 role 的默认变量 |
library/my_module.py | -模块,可以在该角色中使用 |
34.2 创建一个角色
ansible-galaxy init
能为我们构建一个目录模板
[root@node-137 demo]# ansible-galaxy init roles/apache
- Role roles/apache was created successfully
[root@node-137 demo]# tree roles/
roles/
└── apache
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
9 directories, 8 files
回顾我们在前文中写的handler的yml文件,
[root@node-137 ansible]# cat hand-1.yml
---
- hosts: db1
gather_facts: false
vars:
myport: 808
tasks:
- name: install httpd
yum: name=httpd state=present
- name: copy httpd.conf
template: src=httpd.conf1.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd1
- name: start httpd
service: name=httpd state=started
ignore_errors: true
handlers:
- name: restart httpd1
service: name=httpd state=restarted
稍作修改,然后把内容拆分到apache角色的不同目录中
- 把tasks的内容写到
roles/apache/tasks/main.yml
中
[root@node-137 ansible]# cat demo/roles/apache/tasks/main.yml
---
# tasks file for roles/apache
- name: install httpd
yum: name=httpd state=present
- name: copy httpd.conf
template: src=httpd.conf1.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd1
- name: start httpd
service: name=httpd state=started
ignore_errors: true
- 把handlers的内容写到
demo/roles/apache/handlers/main.yml
中
[root@node-137 ansible]# cat demo/roles/apache/handlers/main.yml
---
# handlers file for roles/apache
- name: restart httpd1
service: name=httpd state=restarted
- 把tasks中template模块拷贝的jinja2文件
httpd.conf1.j2
拷贝到demo/roles/apache/templates/
[root@node-137 ansible]# cp httpd.conf1.j2 demo/roles/apache/templates/
- 把变量
myport
写入demo/roles/apache/vars/main.yml
[root@node-137 ansible]# cat demo/roles/apache/vars/main.yml
---
# vars file for roles/apache
myport: 8080
也可以不把变量写在此处,而是在playbook
中定义变量。如果同时定义了变量,且变量值不同,则角色的vars中定义的变量会生效。
到这里apache
这个角色编写完成
34.3 使用角色
角色写好之后,只要在playbook
中直接调用即可,在playbook的roles
下调用,语法,
roles:
- name: name1
role: rolename1
- name: name2
role: rolename2
...
#或
roles:
- role: rolename1
- role: rolename2
...
示例,
[root@node-137 ansible]# cat demo/role-1.yml
---
- hosts: db1
roles:
- role: apache
[root@node-137 ansible]# ansible-playbook demo/role-1.yml
PLAY [db1] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]
TASK [apache : install httpd] *********************************************************************************************************
ok: [node-138]
TASK [apache : copy httpd.conf] *******************************************************************************************************
changed: [node-138]
TASK [apache : start httpd] ***********************************************************************************************************
ok: [node-138]
RUNNING HANDLER [apache : restart httpd1] *********************************************************************************************
changed: [node-138]
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# ansible db1 -m shell -a " ss -nltpu|grep 8080"
node-138 | CHANGED | rc=0 >>
tcp LISTEN 0 128 [::]:8080 [::]:* users:(("httpd",pid=39775,fd=4),("httpd",pid=39774,fd=4),("httpd",pid=39773,fd=4),("httpd",pid=39772,fd=4),("httpd",pid=39771,fd=4),("httpd",pid=39770,fd=4))
可以看到httpd的端口已经变成了8080
变量可以在角色的defaults
、vars
中定义,或者在playbook
中定义,他们的优先级为:
角色的vars > playbook > 角色defaults
同时定义的话,优先级最高的生效
34.4 系统自带的角色
除了我们自行创建的角色外,系统中也包含了一些内置的角色
安装rhel-system-roles.noarch
[root@node-137 ansible]# yum install rhel-system-roles.noarch -y
安装完成后,在/usr/share/ansible/roles/
目录中会有很多角色,
[root@node-137 ansible]# ll /usr/share/ansible/roles/
...
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.ad_integration
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.certificate
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.cockpit
drwxr-xr-x 8 root root 4096 Dec 21 11:55 rhel-system-roles.crypto_policies
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.firewall
drwxr-xr-x 11 root root 4096 Dec 21 11:55 rhel-system-roles.ha_cluster
drwxr-xr-x 9 root root 302 Dec 21 11:55 rhel-system-roles.journald
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.kdump
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.kernel_settings
drwxr-xr-x 7 root root 4096 Dec 21 11:55 rhel-system-roles.logging
drwxr-xr-x 8 root root 4096 Dec 21 11:55 rhel-system-roles.metrics
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.nbde_client
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.nbde_server
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.network
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.podman
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.postfix
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.rhc
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.selinux
drwxr-xr-x 8 root root 4096 Dec 21 11:55 rhel-system-roles.ssh
drwxr-xr-x 9 root root 211 Dec 21 11:55 rhel-system-roles.sshd
drwxr-xr-x 9 root root 4096 Dec 21 11:55 rhel-system-roles.storage
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.timesync
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.tlog
drwxr-xr-x 10 root root 4096 Dec 21 11:55 rhel-system-roles.vpn
下面演示rhel-system-roles.selinux
这个角色,把此目录拷贝到roles
目录中,查看默认的变量
[root@node-137 roles]# cat rhel-system-roles.selinux/defaults/main.yml
---
selinux_state: null
selinux_policy: null
...
其中第一个变量是selinux_state
,这个变量用于指定SELinux
模式,默认值为null
。可以在playbook
中定义这个变量,覆盖默认变量值,命令如下,
[root@node-137 demo]# cat role-2.yml
---
- hosts: db1
vars:
selinux_state: enforcing
roles:
- role: rhel-system-roles.selinux
查看node-138
的selinux的模式
[root@node-138 ~]# getenforce
Permissive
运行此playbook,命令如下,
[root@node-137 ansible]# ansible-playbook demo/role-2.yml
PLAY [db1] *******************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************
ok: [node-138]
...
PLAY RECAP *******************************************************************************************************************************
node-138 : ok=7 changed=1 unreachable=0 failed=0 skipped=18 rescued=0 ignored=0
查看node-138
的selinux的模式
[root@node-138 ~]# getenforce
Enforcing
34.5 修改端口上下文
使用角色rhel-system-roles.selinux
修改端口上下文
查看默认的变量
[root@node-137 ansible]# cat demo/roles/rhel-system-roles.selinux/defaults/main.yml
---
selinux_state: null
selinux_policy: null
...
selinux_ports: []
...
这里变量selinux_ports是一个列表,里面的元素需要定义多个变量,但是变量名无法确认
查看roles/rhel-system-roles.selinux/tasks/main.yml
中关于端口上下文的定义,
[root@node-137 ansible]# cat demo/roles/rhel-system-roles.selinux/tasks/main.yml
...
- name: Set an SELinux label on a port
local_seport:
ports: "{{ item.ports }}"
proto: "{{ item.proto | default('tcp') }}"
setype: "{{ item.setype }}"
state: "{{ item.state | default('present') }}"
local: "{{ item.local | default(False) }}"
with_items: "{{ selinux_ports }}"
...
其中,proto
、state
和local
有默认值,而ports
和setype
没有默认值,所以我们在定义selinux_ports
时,至少要在列表的元素中定义ports
和setype
这两个变量。
修改demo/role-2.yml
,该剧本含义是放行800
端口,让httpd
能运行
[root@node-137 ansible]# cat demo/role-2.yml
---
- hosts: db1
vars:
myport: 800
selinux_ports:
- ports: "{{myport}}"
setype: http_port_t
roles:
- role: rhel-system-roles.selinux
- role: apache
运行之前我们还需要注释掉角色apache/vars
中定义的端口变量,否则httpd无法重启
[root@node-137 ansible]# cat demo/roles/apache/vars/main.yml
---
# vars file for roles/apache
# myport: 8080
运行playbook
[root@node-137 ansible]# ansible-playbook demo/role-2.yml
...
[root@node-138 ~]# ss -nltpu
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
...
tcp LISTEN 0 128 [::]:800 [::]:* users:(("httpd",pid=44097,fd=4),("httpd",pid=44096,fd=4),("httpd",pid=44095,fd=4),("httpd",pid=44094,fd=4),("httpd",pid=44093,fd=4),("httpd",pid=44092,fd=4))
可以看到此时httpd的端口已经是800
34.6 使用ansible Galaxy
参考 https://blog.csdn.net/u010230019/article/details/128564156
在浏览器打开https://galaxy.ansible.com
,里面存有大量的ansible所能用到的角色
以vsftpd
为例
```bash
[root@node-137 ansible]# ansible-galaxy role install weareinteractive.vsftpd
## 第 35 章 ansible加密
前面写了很多playbook,这些playbook都是以明文的方式存在的,有时想对这些playbook进行加密,可以使用`ansible-vault`命令实现。
本章中的示例都将在`demo-vault`中操作,先创建目录,然后把必要文件拷贝进去
```bash
[root@node-137 ansible]# mkdir demo-vault
[root@node-137 ansible]# cp ansible.cfg hosts demo-vault/
[root@node-137 ansible]# cd demo-vault/
35.1 对整个脚本进行加密
加密方式
ansible-vault encrypt file
创建一个playbook,
[root@node-137 demo-vault]# cat vault-1.yml
---
- hosts: db1
gather_facts: false
vars:
aa: "aa"
tasks:
- debug: msg={{aa}}
对vault-1.yml
进行加密
[root@node-137 demo-vault]# ansible-vault encrypt vault-1.yml
New Vault password:
Confirm New Vault password:
Encryption successful
查看vault-1.yml
内容
[root@node-137 demo-vault]# cat vault-1.yml
$ANSIBLE_VAULT;1.1;AES256
35653333336635633965646262613166333264383636306532323433383064613037643762356235
...
66316263666165363830313763383061663431393331623563353466626562316232396537336264
3035
35.2 查看文件内容
查看密文内容,可以使用下面命令,并需要输入密码
ansible-vault view file
查看
[root@node-137 demo-vault]# ansible-vault view vault-1.yml
Vault password:
---
- hosts: db1
gather_facts: false
vars:
aa: "aa"
tasks:
- debug: msg={{aa}}
35.3 运行playbook
如果直接运行加密后的YAML文件,则会报错。此时需要加选项--ask-vault-pass
提示用户输入密码
ansible-playbook --ask-vault-pass var-encrypt.yml
运行,
[root@node-137 demo-vault]# ansible-playbook --ask-vault-pass vault-1.yml
Vault password:
PLAY [db1] *******************************************************************************************************************************
TASK [debug] *****************************************************************************************************************************
ok: [node-138] => {
"msg": "aa"
}
PLAY RECAP *******************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
修改密码使用rekey
,格式
ansible-vault rekey file.yml
修改密码
[root@node-137 demo-vault]# ansible-vault rekey vault-1.yml
Vault password: #原密码
New Vault password: #新密码
Confirm New Vault password: #新密码
Rekey successful
35.4 对脚本进行解密
使用decrypt
选项对密文解密,解密后的YAML文件将是明文显示,格式
ansible-vault decrypt file.yml
解密,
[root@node-137 demo-vault]# ansible-vault decrypt vault-1.yml
Vault password:
Decryption successful
[root@node-137 demo-vault]# cat vault-1.yml
---
- hosts: db1
gather_facts: false
vars:
aa: "aa"
tasks:
- debug: msg={{aa}}
35.5 使用密码文件
加密,解密及查看等操作都需要输入密码,可以把密码写入一个文件中。在执行ansible-vault
命令时加上--vault-id 密码文件
即可使用密码文件。
- 把密码写入文件
[root@node-137 demo-vault]# echo haha > encrypt.txt
[root@node-137 demo-vault]# cat encrypt.txt
haha
- 对文件加密
[root@node-137 demo-vault]# ansible-vault encrypt --vault-id encrypt.txt vault-1.yml
Encryption successful
[root@node-137 demo-vault]# cat vault-1.yml
$ANSIBLE_VAULT;1.1;AES256
65663635316664393833666535363563336361363231366536393366613661656534333430313964
...
38393964653165353334666535646634396237323361333262346636333239343335383362346336
3536
- 查看文件
[root@node-137 demo-vault]# ansible-vault view --vault-id encrypt.txt vault-1.yml
---
- hosts: db1
gather_facts: false
vars:
aa: "aa"
tasks:
- debug: msg={{aa}}
- 运行playbook,同样使用该选项
[root@node-137 demo-vault]# ansible-playbook --vault-id encrypt.txt vault-1.yml
PLAY [db1] *************************************************************************************************************************...
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- 解密文件
[root@node-137 demo-vault]# ansible-vault decrypt --vault-id encrypt.txt vault-1.yml
Decryption successful
35.6 对单个字符串进行加密
可以对playbook中的某个字符串进行加密,例如,对haha
进行加密
- 生成密文
[root@node-137 demo-vault]# ansible-vault encrypt_string --vault-id encrypt.txt haha
!vault |
$ANSIBLE_VAULT;1.1;AES256
39623761313165663038353036333433326333343137666261623165326133646231343539376662
...
3033663961373262390a383630636562303633386666623165343138353535656564623262386165
6432
Encryption successful
这里仅是根据密码文件对haha
生成密文
手动
修改vault-1.yml文件
[root@node-137 demo-vault]# cat vault-1.yml
---
- hosts: db1
gather_facts: false
vars:
aa: !vault |
$ANSIBLE_VAULT;1.1;AES256
39623761313165663038353036333433326333343137666261623165326133646231343539376662
...
3033663961373262390a383630636562303633386666623165343138353535656564623262386165
6432
tasks:
- debug: msg={{aa}}
这里需要注意:变量名aa后面的变量值,不能用引号引起来
- 运行playbook,并指定密码文件
[root@node-137 demo-vault]# ansible-playbook --vault-id encrypt.txt vault-1.yml
PLAY [db1] *******************************************************************************************************************************
TASK [debug] *****************************************************************************************************************************
ok: [node-138] => {
"msg": "haha"
}
PLAY RECAP *******************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
至此,本系列文章撰写完毕