Ansible角色 使用Ansible角色可以有更多的机会去重用以前便携的Playbook中的代码。可以在标准化目录结构中打包所有任务、变量、文件、模版以及调配基础架构或部署应用其他资源。
除了自行编写、使用角色外,也可从其他来源获取角色。常用红帽企业Linux管理角色包含在rhel-system-roles
软件包中可以方便的去使用。也可以从Ansible Galaxy网站获取由社区提供的其他角色。
使用ansible-galaxy list
可以看到在在当前Ansible配置环境下找到了Role角色列表。
那么Ansible怎么发现这些Role呢?这些Role的路径在ansible.cfg配置文件中已经定义好了,每个目录之间通过冒号分隔:
1 2 3 4 [defaults] inventory =./inventoryremote_user =devopsroles_path =./roles:/usr/share/ansible/roles:/etc/ansible/roles
Ansible角色子目录
子目录
描述
defaults
此目录中的main.yml文件包含角色变量的默认值,使用角色时可以覆盖这些默认值。这些变量的优先级较低,应该在Play中更改和定义。
files
此目录包含由角色要处理的全部静态文件
handles
此目录中的main.yml文件包含角色的处理程序
meta
main.yml中包含角色相关信息,如作者、许可证、平台、角色依赖项
tasks
main.yml中包含角色任务的定义
templates
此目录包含角色引用的template模板
tests
此目录包含清单和test.yml Playbook,用于进行测试
vars
此目录的main.yml文件定义角色的变量值。这些变量通常用于角色内部用途。这些变量的优先级较高,不应在Playbook中覆盖修改
定义变量和默认值 对于角色变量可以通过在vars目录下的main.yml文件来定义。与其他变量一样,使用这些变量需要在角色文件中引入{{ VARS_NAME }}
。这些变量具有较高的优先级,无法被Ansible中清单变量覆盖。
默认变量在defaults目录下的main.yml文件中定义。它们的变量优先级是最低的,任何定义变量的形式都会将其覆盖,所以更改默认变量可以使Play操作更精准、更适合受控主机。
可以在vars/main.yml或defaults/main.yml中定义具体的变量,但没必要在两者中都定义变量。
在Playbook中使用Ansible角色 可以在Play中引入roles即可使用。
1 2 3 4 - hosts: remote server roles: - role1 - role2
角色中使用的任何copy、script、template或include_tasks/import_tasks任务都可以引用角色中相关的文件、模版或任务文件,并且无需使用相对路径或绝对路径,因为Ansible会自动在角色的files、templates、tasks子目录下去寻找他们。
控制执行顺序 在Ansible中的每一个Play是会按照Play的顺序依次执行。在每个Play中如果定义了角色,那么会优先运行角色,之后再运行任务。在最后执行被激活的handles处理程序。
在某些情况下,可能需要在执行角色任务之前执行一些任务,你可以为Play配置pre_tasks
部分,这样就可以在运行角色之前执行一部分任务。如果配置在pre_tasks
中的任务出发了handles处理程序。那么也会在角色或其他普通任务之前执行处理程序。
当然也可以使用为Play配置post_tasks
部分,来让任务在普通任务之后和激活的处理程序之后再运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --- - name: Play to illustrate order hosts: example.com pre_tasks: - debug: msg: "I am pre task" notify: my handler roles: - role1 tasks: - debug: msg: "I am nomal task" notify: my handler post_tasks: - debug: msg: "I am posted handler" ...
上面的例子中,每个任务部分都会执行debug任务来通知my handler处理程序。my handler任务执行了三次:
第一次在执行了所有的pre_tasks任务后执行处理程序
第二次在执行角色结束后的普通tasks任务后执行
第三次是在执行完post_tasks任务后执行处理程序
除了将角色包含在Play中的roles部分外,也可以将角色添加到普通的tasks中。使用include_role
模块可以动态包含角色,使用import_role
模块可以静态导入角色。
1 2 3 4 5 6 7 8 9 10 11 12 --- - name: Execute a role as a task hosts: localhost tasks: - name: a simple task debug: msg: "Im first task" - name: "A task to include role here" include_role: name: linux-system-roles.network ...
RHEL 系统角色 RHEL红帽系统中,从Linux 7.4开始,系统内随附了多个Ansible角色。它们位于rhel-system-roles
软件包内。RHEL8中,需要启动AppStream仓库来安装此软件包。
角色名
描述
rhel-system-roles.kdump
配置kdump崩溃恢复服务
rhel-system-roles.network
配置网络
rhel-system-roles.postfix
配置postfix服务为每个主机配置邮件传输代理
rhel-system-roles.selinux
配置和管理SELinux自定义,包括模式、文件、端口上下文、布尔值设置和SELinux用户
rhel-system-roles.timesync
使用网络时间协议配置时间同步
访问RHEL系统角色文档 安装后,这些RHEL系统角色文档存放在/usr/share/doc/rhel-system-roles
中,其中还包含了如何去使用以及使用的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ├── kdump │ ├── COPYING │ ├── README.html │ └── README.md ├── network │ ├── example-bond-with-vlan-playbook.yml │ ├── example-bridge-with-vlan-playbook.yml │ ├── example-down-profile-playbook.yml │ ├── example-eth-simple-auto-playbook.yml │ ├── example-eth-with-vlan-playbook.yml │ ├── example-infiniband-playbook.yml │ ├── example-inventory │ ├── example-macvlan-playbook.yml │ ├── example-remove-profile-playbook.yml │ ├── LICENSE │ ├── README.html │ └── README.md ├── postfix │ ├── COPYING │ ├── README.html │ └── README.md ├── selinux │ ├── COPYING │ ├── example-selinux-playbook.yml │ ├── README.html │ └── README.md └── timesync ├── COPYING ├── example-timesync-playbook.yml ├── example-timesync-pool-playbook.yml ├── README.html └── README.md
时间同步角色例子 如果为受控主机配置NTP时间同步服务,那么可以使用rhel-system-roles.timesync
角色自动化配置。
通过/usr/share/doc/rhel-system-roles/timesync/README.md
查看示例和需要用到的变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 --- - name: Config NTP sync service hosts: all vars: timesync_ntp_servers: - hostname: 0. rhel.pool.ntp.org iburst: yes - hostname: 1. rhel.pool.ntp.org iburst: yes timezone: Asia/Shanghai roles: - rhel-system-roles.timesync tasks: - name: Set TimeZone timezone: name: "{{ timezone }} " ...
也可以把在Play中定义的变量放到变量文件中。将变量文件可以放到group_vars
或host_vars
子目录中。
配置SELinux角色 使用linux-system-roles.selinux
角色控制SELinux行为。t
通过/usr/share/doc/rhel-system-roles/selinux/README.md
查看示例和需要用到的变量。
设置SELinux运行模式 变量 selinux_state: enforcing
。可以设置为enforing、permissive、disabled。如果不设置则不更改。
设置SELinux布尔值 例如将httpd_enable_homedirs布尔值永久设置为no
1 2 3 4 selinux_booleans: - name: 'http_enable_homedirs' state: 'on' persistent: 'yes'
设置SELinux fcontext上下文 下面的例子完成了对/srv/www
目录下的所有文件的默认SELinux类型设置为httpd_sys_content_t
。
1 2 3 4 selinux_fcontexts: - target: '/srv/www(/.*)?' setype: 'httpd_sys_content_t' state: present
使用selinux_restore_dirs
变量指定要对其运行restorecon
目录的列表。
设置SELinux端口 使用selinux_ports
变量可以对端口进行管理。
1 2 3 4 5 selinux_ports: - ports: '82' setype: 'http_port_t' proto: 'tcp' state: 'present'
创建角色框架 创建角色不需要额外的开发工具,角色是文件目录结构和文件组成的。可以使用创建目录和编辑文件命令配合完成创建一个角色框架。为了节省时间,可以使用ansible-galaxy init
来创建角色框架。
ansible-galaxy init my_role
1 2 $ ls my_role/ defaults files handlers meta README.md tasks templates tests vars
默认变量的覆盖 在以下情况中,角色中defaults目录中定义的默认变量会被覆盖:
在清单文件中定义,作为主机变量或组变量
在playbook项目的group_vars或hosts_vars目录下的YAML文件中定义
作为变量嵌套Play的vars关键字中定义
在Play的定义roles角色时的所定义的变量
安装V2ray-core服务角色示例 功能如下:
自动安装最新版本
按照受控节点平台自动选择platform平台
可以选择从Github/Jsdelivr/用户自定义V2ray-core地址下载
可以控制卸载
Tasks角色任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 --- - name: Prepare to Install V2ray-core block: - name: V2ray download path is exist file: path: "{{ v2ray_download_path }} " state: directory mode: 0755 - set_fact: install_error: false when: v2ray_present - name: Get the latest V2ray version and servers info block: - name: Get Server machine platform shell: | case "${1:-"{{ ansible_facts.machine }}"}" in i686|i386) echo '32' ;; x86_64|amd64) echo '64' ;; *armv7*|armv6l) echo 'arm' ;; *armv8*|aarch64) echo 'arm64' ;; *mips64le*) echo 'mips64le' ;; *mips64*) echo 'mips64' ;; *mipsle*) echo 'mipsle' ;; *mips*) echo 'mips' ;; *s390x*) echo 's390x' ;; ppc64le) echo 'ppc64le' ;; ppc64) echo 'ppc64' ;; *) return 1 ;; esac register: return_machine - name: Get the latest V2ray version and servers info shell: > curl -H "Accept: application/json" -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20180101 Firefox/74.0" -s "https://api.github.com/repos/v2ray/v2ray-core/releases/latest" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4 register: return_version args: warn: false - set_fact: latest_v2ray: "{{ return_version.stdout_lines[0] }} " machine: "{{ return_machine.stdout }} " rescue: - name: "ERROR: Get the latest V2ray version and servers info. Please check your Network Connection and V2ray-core version" set_fact: install_error: true when: v2ray_present and not install_error - name: Download V2ray-core block: - name: "Download V2ray-core{{ latest_v2ray }} from jsdelivr" get_url: url: "https://cdn.jsdelivr.net/gh/v2ray/dist/v2ray-linux-{{ machine }} .zip" dest: "{{ v2ray_download_path }} " when: v2ray_download_from == "jsdelivr" - name: "Download V2ray-core{{ latest_v2ray }} from Github" get_url: url: "https://github.com/v2ray/v2ray-core/releases/download/{{ latest_v2ray }} /v2ray-linux-{{ machine }} .zip" dest: "{{ v2ray_download_path }} " when: v2ray_download_from == "Github" - name: "Download V2ray-core{{ latest_v2ray }} from {{ v2ray_download_from }} " get_url: url: "{{ v2ray_download_from }} " dest: "{{ v2ray_download_path }} " when: | v2ray_download_from != "jsdelivr" and v2ray_download_from != "Github" rescue: - name: "ERROR: Download V2ray-core. Please check your Network Connection and V2ray-core version" set_fact: install_error: true when: v2ray_present and not install_error - name: Unarchive V2ray-core block: - name: Create unarchive V2ray-core directory file: path: "{{ v2ray_download_path }} /v2ray-linux-{{ machine }} " state: directory mode: 0755 - name: Unarchive V2ray-core unarchive: src: "{{ v2ray_download_path }} /v2ray-linux-{{ machine }} .zip" dest: "{{ v2ray_download_path }} /v2ray-linux-{{ machine }} " remote_src: true rescue: - name: "ERROR: Unarchive V2ray-core. Please check your platform" set_fact: install_error: true when: v2ray_present and not install_error - name: Install V2ray-core and Start V2ray-core block: - name: Create V2ray install directory file: path: "{{ item }} " state: directory mode: 0755 loop: "{{ v2ray_installed_dir }} " - name: Copy binary file into directory copy: src: "{{ v2ray_download_path }} /v2ray-linux-{{ machine }} /{{ item.src }} " dest: "{{ item.dest }} " remote_src: true mode: 0755 loop: "{{ v2ray_binary }} " - name: Copy V2ray config and Start V2ray-core copy: src: "{{ v2ray_config }} " dest: /etc/v2ray/config.json mode: 0755 notify: Start V2ray Service rescue: - name: "ERROR: Install V2ray-core. Please check your permissions" set_fact: install_error: true when: v2ray_present and not install_error - name: Remove v2ray-core block: - name: Stop V2ray-core service systemd: name: v2ray.service daemon_reload: true enabled: false state: stopped ignore_errors: true - name: Remove V2ray-core service file: path: /etc/systemd/system/v2ray.service state: absent - name: Remove v2ray-core file file: path: "{{ item }} " state: absent loop: "{{ v2ray_installed_dir }} " when: not v2ray_present or install_error - name: Check remove result debug: msg: Removed v2ray-core when: not v2ray_present - name: Check install result debug: msg: Install V2ray-core Failure failed_when: yes when: v2ray_present and install_error - name: Check install result debug: msg: Install V2ray-core Successful when: v2ray_present and not install_error
Default变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 v2ray_download_from: "Github" v2ray_download_path: "/tmp/v2ray" v2ray_config: "files/v2ray.conf" v2ray_present: true v2ray_installed_dir: - /etc/v2ray - /var/log/v2ray - /usr/bin/v2ray - "{{ v2ray_download_path }} " v2ray_binary: - src: geoip.dat dest: /usr/bin/v2ray - src: geosite.dat dest: /usr/bin/v2ray - src: v2ctl dest: /usr/bin/v2ray - src: v2ray dest: /usr/bin/v2ray - src: systemd/v2ray.service dest: /etc/systemd/system