华子目录
- 前言
- `playbook`概念
- `playbook`结构理解
- `playbook`核心元素
- `playbook`特点与优势
- `playbook`基本语法
- `ansible-playbook`命令
- ansible总结
- 查看主机清单
- ansible配置文件
- 单个play
- 语法检测
- 运行
- 多个play
- 查看模块doc
- 变量
- 事实变量
- 导入变量文件
- 字典变量
- 机密数据管理
- 在`playbook`中导入变量文件
- 导入加密变量文件和普通文件
- register
- 流程控制
- ansible中的循环机制`loop`
- when
- `notify`与`handlers`
- ignore_errors
- block,rescue,always
- changed_when
- 包含文件与导入文件
- 角色
- 列出角色
- 运行角色
- 安装collection
- 列出colection
- `pre_tasks` `post_tasks`
- 总结
前言
- 在
Ansible
中,playbooks
(剧本
)是用来定义一系列task任务
的文件,可以实现自动化部署、配置和管理服务器等操作 - 本文主要介绍
playbook
剧本的组成以及编写
playbook
概念
playbook
是 一个不同于
使用Ansible命令行
执行方式的模式,其功能更强大灵活playbook
是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础playbook
实质就是一个文件,有着特定的组织格式,它采用的语法格式是yaml
(Yet Another Markup Language
)playbook
是由一个或多个play
组成的列表
playbook
结构理解
-
集合
:多个模块
的集合体
-
任务清单
:playbook
- 一个
playbook
中可以有多个play
(playbook
是play
的集合体) - 一个
play
中可以有多个任务task
(每个play
可以单独指定主机范围
)(task
只能在其所属play
中指定的主机上
执行)(每个task
当中可以存在多个ansible操作模块
)
- 一个
-
除了
playbook
之外,还有playbook
需要的模板,文件,变量文件
等等不能全都放在playbook
中,否则会使得playbook
变得臃肿
。我们就需要单独进行存放
。 -
最后,我们会把
playbook
,playbook
需要的模板,文件,变量文件
等等进行打包
。形成一个角色role
playbook
核心元素
hosts主机列表
:远程主机列表
task任务集
:通过task
调用ansible
的模板将多个操作组织在一个playbook
中运行variables变量
:用来存储数据
,可以在playbook
中被引用。这些变量可以是全局
的,也可以是针对特定主机或主机组的
。使用变量可以使playbook
更加灵活和可重用templates模板
:一种用来生成配置文件
或者其他文本文件
的机制
。在Ansible
中,你可以使用Jinja2模板引擎
来创建模板文件
。这些模板文件中可以包含变量、条件语句、循环等
,使得你可以根据不同的情况生成不同的文本内容handlers处理器
:一种特殊类型
的任务
,它们仅在特定条件下触发
。通常用于在一组任务执行完成后
执行诸如修改配置文件
后重启服务
之类的操作。当服务配置
文件changed被修改
需要重启服务
进行重新加载
时,触发
执行的操作handlers
和notity
结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
roles角色
:用来组织playbooks
中任务的结构化方式。一个role
包含了一组相关的任务、变量、handlers、文件等
内容,可以使得playbooks
更加模块化
、可重用和易于维护tags标签
,指定某条任务执行
,用于选择运行playbook
中的部分代码
remote_user
:在远程主机
以哪个用户
身份执行;
playbook
特点与优势
声明式
:用户只需描述期望的系统状态
,而非具体的操作步骤,Ansible
负责确定如何达到这一状态
幂等性
:Playbook
设计为可重复执行
,即使在系统已处于预期状态时,再次运行也不会
产生副作用
可读性强
:yaml
格式和简洁的结构使得Playbook
易于编写和维护模块丰富
:Ansible
提供了大量的模块
,覆盖了从系统配置到云资源管理的广泛需求跨平台
:支持多种操作系统
和环境
,适配不同的自动化需求
playbook
基本语法
playbook
使用yaml
语法格式,后缀可以是yaml
,也可以是yml
- 第一种写法:
[root@server ~]# vim test.yaml
--- #yaml文件以---开头,以表明这是一个yaml文件,可省略
- name: first-play #定义一个play的名称,可省略
hosts: all # -表示一个块序列的节点,注意:横杠后面有空格,可以写主机名,主机组名,多个主机名使用逗号隔开
remote_user: root #指定在进行远程操作时使用root用户进行操作
become: true #是否提权
become_user: root #提权的用户为root
tasks: #使用tasks关键字指明要进行操作的任务列表,之后的行都属于tasks键值对中的值
- name: PING!!! #每个任务都以-开头,每个任务都有自己的名字(名字自定义),任务名使用name关键字进行指定
ping: #ansible中的ping模块
- name: make directory!!! #第二个任务名(任务名自定义)
file: #ansible中的file模块
path: /root/data
state: directory
-
注意:键值对之间必须要有一个
空格
-
第二种写法:(
推荐写法
)
[root@server ~]# vim test1.yaml
--- # ---表示文档开始
- name: first-play #定义一个play的名称,可省略
hosts: node1.example.com # -表示一个块序列的节点,注意:横杠后面有空格,可以写主机名,主机组名,多个主机名使用逗号隔开
remote_user: root #指定在进行远程操作时使用root用户进行操作
become: true #是否提权
become_user: root #提权的用户为root
vars: #表示下面是定义的变量
filename: file1 #变量的形式,key: value
vars_files: #导入变量文件,相当于include。对于导入的变量文件中的变量,直接使用即可
- /home/student/data-secret/secret.yml #加密变量文件
- ./user.yml #普通变量文件
tasks: #使用tasks关键字指明要进行操作的任务列表,之后的行都属于tasks键值对中的值
- name: touch file!!! #第一个任务名(任务名自定义)
file: path=/root/{{ filename }} state=touch #file为ansible的模块,file:后接模块参数(使用=号)
- 使用
{{ key }}
引用变量的值
name
下面接模块名
ansible-playbook
命令
[root@server ~]# ansible-playbook [options] playbook.yml
参数 | 说明 |
---|---|
-i | 指定inventory 文件的路径,用于指定要管理的主机清单 |
-k | 用来交互输入ssh 密码 |
-K | 用来交互输入sudo (普通用户)密码 |
-u | 指定用户 |
-l | 指定要运行剧本的主机或主机组 |
-e | 命令行中指定变量 ,当与剧本中的变量名重复时,会覆盖剧本中变量 |
-t | 指定要运行的标签 ,只运行带有指定标签的任务 |
--syntax-check | 检查yaml 文件的语法是否正确 |
--step | 执行tasks 中的任务,需要手动确认是否往下执行 |
--list-tasks | 列出剧本中的所有任务 |
--list-hosts | 检查生效的主机 |
--start-at-task | 指定从某个task 开始运行,如--start-at-task='install httpd' |
-C | 测试运行playbook ,但不显示测试结果 |
[root@server ~]# ansible-playbook playbook.yaml --syntax-check #检查yaml文件的语法是否正确
[root@server ~]# ansible-playbook playbook.yaml --list-task #列出task任务
[root@server ~]# ansible-playbook playbook.yaml --list-hosts #检测生效的主机
[root@server ~]# ansible-playbook -C playbook.yaml #-C测试运行(没有运行结果)
- 执行
playbook
剧本
[root@server ~]# ansible-playbook playbook.yaml
ansible总结
- 在
ansible
中,ansible.cfg
和hosts
文件是ansible
的默认配置文件,如果在当前目录运行ansible指令
的时候,当前目录下有ansible.cfg
或hosts
文件,就会加载当前目录的
。如果当前目录
下没有ansible.cfg
或hosts
文件,ansible
就会加载/etc/ansible/ansible.cfg
或/etc/ansible/hosts
文件
查看主机清单
[student@workstation ~]$ ansible-navigator inventory -i 清单文件目录 -m stdout --graph
[student@workstation ~]$ ansible-inventory --graph
ansible配置文件
- 自动生成配置文件
[student@workstation ~]$ ansible-config init --disabled > ansible.cfg #在当前目录下生成ansible配置文件
- 手动编辑
[student@workstation ~]$ vim ansible.cfg
[defaults]
inventory=inventory #定义主机清单
collections_path=mycollections
roles_path=roles
remote_user=root #在受管主机上登录的用户名称
ask_pass=false #是否询问ssh密码
vault_password_file=secret.txt #存放密码的文件
[privilege_escalation] #权限升级
become=true
become_method=sudo #提升权限的方法
become_ask_pass=false #是否为become_method提示输入密码
become_user=root #切换到的用户
单个play
-
每一个
play
管理一部分主机
-
一个
play
管理一部分主机
语法检测
[student@workstation playbook-basic]$ ansible-navigator run -m stdout site.yml --syntax-check #语法检测
运行
[student@workstation playbook-basic]$ ansible-navigator run -m stdout site.yml #运行ansible脚本,对于幂指型重复运行不会有影响。但是对command,shell,raw这样的非幂指型有影响
多个play
[student@workstation playbook-multi]$ vim intranet.yml
---
- name: enable intranet services
hosts: servera
become: true #提权
become_user: root #提权为root用户
tasks:
- name: latest version of httpd and firewalld installed
ansible.builtin.dnf:
name:
- httpd #使用列表的形式,安装多个软件包
- firewalld
state: latest
- name: test html page is installed
ansible.builtin.copy:
content: "welcome to the example.com intranet\n" #复制的内容,\n表示换行
dest: /var/www/html/index.html #复制到的位置
- name: firewalld started
ansible.builtin.service: #开启firewalld
name: firewalld
state: started
enabled: true
- name: firewall permit httpd
ansible.posix.firewalld:
service: http #服务名
permanent: true #设置为永久性
state: enabled #放行http
immediate: yes #不用重启,立即生效
- name: httpd started
ansible.builtin.service:
name: httpd #服务名
state: started #设置为开启
enabled: true #开机自启动
- name: test intranet web server
hosts: localhost #本机
become: false #是否提升权限
tasks:
- name: connect to intranet web server
ansible.builtin.uri:
url: http://servera.lab.example.com #访问的网址
return_content: yes #是否返回内容
status_code: 200 #判断是否访问成功
[student@workstation playbook-review]$ vim internet.yml
---
- name: enable internet web service
hosts: serverb.lab.example.com
become: true
tasks:
- name: firewalld httpd mariadb php php-mysqlnd installed #安装多个软件包
ansible.builtin.dnf:
name:
- firewalld
- httpd
- mariadb-server
- php
- php-mysqlnd
state: latest
- name: firewalld enabled #启动防火墙
ansible.builtin.service:
name: firewalld
state: started
enabled: true
- name: permit httpd #放行http服务
ansible.posix.firewalld:
service: http
state: enabled
permanent: true
immediate: yes
- name: httpd enabled #httpd开机自启动
ansible.builtin.service:
name: httpd
state: started
enabled: true
- name: mariadb enabled #mariadb开机自启动
ansible.builtin.service:
name: mariadb
state: started
enabled: true
- name: copy index.php #copy文件并设置文件权限
ansible.builtin.copy:
src: index.php
dest: /var/www/html/index.php
mode: 0644
- name: test web server
hosts: workstation
become: false
tasks:
- name: connect to server
ansible.builtin.uri:
url: http://serverb.lab.example.com
status_code: 200
查看模块doc
[student@workstation playbook-multi]$ ansible-doc --list | grep uri
debug Print statements during exec...
uri Interacts with webservices
[student@workstation playbook-multi]$ ansible-doc -l | grep uri
debug Print statements during exec...
uri Interacts with webservices
[student@workstation playbook-multi]$ ansible-doc uri #查看uri模块的详细信息
变量
- 在
playbook
中定义变量
[student@workstation data-variables]$ vim playbook.yml
---
- name: deploy and start apache httpd service
hosts: webserver
vars: #在yml文件中定义变量
web_pkg: httpd
firewall_pkg: firewalld
web_service: httpd
firewall_service: firewalld
python_pkg: python3-PyMySQL
rule: http
tasks:
- name: install packages
ansible.builtin.dnf: #安装软件包
name:
- "{{ web_pkg }}" #引用变量
- "{{ firewall_pkg }}"
- "{{ python_pkg }}"
state: latest
- name: firewalld enabled #启动firewalld
ansible.builtin.service:
name: "{{ firewall_service }}"
state: started
enabled: true
- name: firewalld rule to http #放行防火墙规则
ansible.posix.firewalld:
service: "{{ rule }}"
state: enabled
permanent: true
immediate: yes
- name: copy file to http #创建网页文件
ansible.builtin.copy:
content: "Example web content\n"
dest: /var/www/html/index.html
- name: httpd enabled #启动httpd服务
ansible.builtin.service:
name: "{{ web_service }}"
state: started
enabled: true
- name: verify http service #http服务检测是否正常
hosts: workstation
become: false
tasks:
- name: look http server
ansible.builtin.uri:
url: http://servera.lab.example.com
status_code: 200 #检测是否为200,不是200会报错
事实变量
-
事实变量:收集到的远程主机的
主机名,ip地址
等等 -
setup
模块自动在playbook
执行时被触发
,并且收集到的信息默认就被存储在Ansible
的变量
中(ansible_facts
变量)
[student@workstation data-variables]$ ansible all -m setup #会在当前目录下寻找清单文件中的所有主机的事实
如何引用事实变量
[student@workstation data-facts]$ vim dispaly_facts.yml
---
- name: display ansible facts
hosts: webserver
tasks:
- name: display all facts
ansible.builtin.debug:
msg: "{{ ansible_facts['fqdn'] }}"
导入变量文件
- 使用
vars_files
参数
[student@workstation data-secret]$ vim create_users.yml
---
- name: create user
hosts: devservers
become: true
remote_user: devops
vars_files: #该加密变量文件密码是redhat (文件变量列表可以有多个,也可以有一个)
- /home/student/data-secret/secret.yml #加密变量文件
- ./user.yml #普通变量文件
tasks:
- name: creating user from secret.yml
ansible.builtin.user:
name: "{{ username }}" #直接引用变量即可
password: "{{ pwhash }}"
- name: create user
ansible.builtin.user:
name: "{{ user }}" #直接引用变量即可
password: "{{ passwd }}"
字典变量
- 变量值也可以时字典类型
---
- name: Deploy /etc/hosts file # Playbook 名称
hosts: all # 目标主机组,指定该 Playbook 应用到所有主机
vars:
hosts: # 定义 hosts 变量,包括主机名称和 IP 地址的列表
- { name: 'host1', ip: '192.168.1.2' } # 定义主机1的信息
- { name: 'host2', ip: '192.168.1.3' } # 定义主机2的信息
- { name: 'host3', ip: '192.168.1.4' } # 定义主机3的信息
tasks:
- name: Deploy /etc/hosts from template # 任务名称
template:
src: templates/hosts.j2 # 指定模板文件路径(相对于 templates 目录)
dest: /etc/hosts # 指定模板文件复制到远程主机的目标路径
机密数据管理
- 第一种方式创建机密文件,密码可能容易忘记
[student@workstation ~]$ ansible-vault create secret.yml #创建机密文件,需要设置密码
hello world
[student@workstation ~]$ cat secret.yml #发现内容已加密
- 第二种方式:先创建密码文件,再创建机密文件,机密文件的密码在密码文件中
[student@workstation ~]$ echo huazi > password.txt
[student@workstation ~]$ ansible-vault create --vault-password-file=password.txt secret.yml
hello world
- 查看机密文件内容
[student@workstation ~]$ ansible-vault view secret.yml
Vault password: #这里需要输入密码
hello world
- 查看机密文件内容时,指定密码文件
[student@workstation ~]$ ansible-vault view --vault-password-file=password.txt secret.yml
hello world
- 编辑机密文件(相当于vim)(不能使用vim直接编辑,因为使用vim进入后是密文)
[student@workstation ~]$ ansible-vault edit secret.yml
Vault password: #这里需要输入密码才能进入编辑模式
#指定密码文件,进入机密文件中
[student@workstation ~]$ ansible-vault edit --vault-password-file=password.txt secret.yml
- 解密机密文件
[student@workstation ~]$ ansible-vault decrypt --vault-password-file=password.txt secret.yml
Decryption successful #解密成功
[student@workstation ~]$ cat secret.yml #可以正常查看内容
hello world
- 将普通文件加密为机密文件
[student@workstation ~]$ ansible-vault encrypt --vault-password-file=password.txt secret.yml
Encryption successful #加密成功
[student@workstation ~]$ cat secret.yml #发现为加密内容
- 重置密码
[student@workstation ~]$ ansible-vault rekey secret.yml
Vault password: #huazi 原密码
New Vault password: #redhat 新密码
Confirm New Vault password: #redhat 新密码
Rekey successful
[student@workstation ~]$ ansible-vault view secret.yml
Vault password: #redhat 新密码
hello world
在playbook
中导入变量文件
- 使用
vars_files
导入加密变量文件和普通文件
导入文件后,文件中的变量直接引用即可
[student@workstation data-secret]$ ansible-vault view --vault-password-file=password.txt secr et.yml #查看加密文件内容
username: ansibleuser1
pwhash: $6$jfnHouVKUTFMM1pm$39OVTp0ZL8FX.QbD1GoUCP12pNrTC2XzX9Ec0UhzwAM76A.B.Yrk8S.8xiSSnAc.>
[student@workstation data-secret]$ cat user.yml #查看普通文件内容
user: huazi
passwd: "{{ '123456' | password_hash('sha512') }}" #密码要经过加密才能使用
[student@workstation data-secret]$ vim create_users.yml
---
- name: create user
hosts: devservers
become: true
remote_user: devops
vars_files: #该加密变量文件密码是redhat (文件变量列表可以有多个,也可以有一个)
- /home/student/data-secret/secret.yml #加密变量文件
- ./user.yml #普通变量文件
tasks:
- name: creating user from secret.yml
ansible.builtin.user:
name: "{{ username }}" #直接引用变量即可
password: "{{ pwhash }}"
- name: create user
ansible.builtin.user:
name: "{{ user }}" #直接引用变量即可
password: "{{ passwd }}"
- 由于在
create_users.yml
中导入了机密文件
,所以在执行create_users.yml
文件时,需要--vault-password-file
指定密码文件
[student@workstation data-secret]$ echo redhat > password.txt
[student@workstation data-secret]$ ansible-navigator run -m stdout create_users.yml --vault-password-file=password.txt
register
register
定义的变量会接受模块运行后的所有结果,包括状态,屏幕回显等等。与模块同级,放在模块后面
[student@workstation data-facts]$ vim check_httpd.yml
---
- name: check server
hosts: webserver
tasks:
- name: check
ansible.builtin.command: "systemctl is-active httpd"
register: result #register声明变量
- name: dispaly
ansible.builtin.debug:
var: result.stdout #使用 变量名.stdout 打印systemctl is-active httpd的屏幕回显
流程控制
ansible中的循环机制loop
Ansible
中的循环机制主要通过几个关键元素实现
- 常用
item
和loop
关键字,loop
放在模块的最后面,与模块同级
[student@workstation control-flow]$ vim play.yml
---
- name: print msg
hosts: servera.lab.example.com
vars:
list: #定义变量列表,list为列表名,one two three为列表中的值
- one
- two
- three
tasks:
- name: print
ansible.builtin.debug:
var: "item"
loop: "{{ list }}"
[student@workstation control-flow]$ ansible-navigator run -m stdout play.yml
PLAY [print msg] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
TASK [print] *******************************************************************
ok: [servera.lab.example.com] => (item=one) => {
"ansible_loop_var": "item",
"item": "one"
}
ok: [servera.lab.example.com] => (item=two) => {
"ansible_loop_var": "item",
"item": "two"
}
ok: [servera.lab.example.com] => (item=three) => {
"ansible_loop_var": "item",
"item": "three"
}
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
案例:使用loop
安装多个软件包
[student@workstation control-flow]$ vim playbook.yml
---
- name: mariadb server is running
hosts: database_dev
vars:
mariadb_packages:
- mariadb-server
- python3-PyMySQL
tasks:
- name: install
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"
when
- 在
Ansible
中,提供的唯一一个通用的条件判断是when
指令,当when
指令的返回值为true
时,则该任务执行,否则不执行该任务 when
指令中的变量名不需要
手动加上{{ }}
[student@workstation control-flow]$ vim playbook.yml
---
- name: mariadb server is running
hosts: servera.lab.example.com
vars:
mariadb_packages:
- mariadb-server
- python3-PyMySQL
tasks:
- name: install
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"
when: ansible_facts['fqdn'] == "huazi" #当不满足这个条件时,返回false,不执行
- name: start service
ansible.builtin.service:
name: mariadb
state: started
enabled: true
[student@workstation control-flow]$ ansible-navigator run -m stdout playbook.yml
PLAY [mariadb server is running] ***********************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
TASK [install] *****************************************************************
skipping: [servera.lab.example.com] => (item=mariadb-server) #skipping表示条件不满足,跳过了
skipping: [servera.lab.example.com] => (item=python3-PyMySQL)
TASK [start service] ***********************************************************
ok: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
notify
与handlers
-
notify
下的名字必须和handlers
中的name
的名字相同。 -
handlers
会等上面任务执行完成后再执行 -
notify
放在模块的最后,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。 -
在系统中,我们修改了服务器的配置文件,这时候就需要重启服务,就可以使用到
handlers
。配合notify
使用 -
handlers
等价于playbook
中的tasks
的位置
[student@workstation control-flow]$ vim plalbook.yml
---
- name: restart http service
hosts: servera.lab.example.com
tasks:
- name: httpd installed #安装httpd
ansible.builtin.dnf:
name: httpd
state: present
- name: httpd started #启动httpd
ansible.builtin.service:
name: httpd
state: started
enabled: true
- name: reset index.html #修改网页内容
ansible.builtin.copy:
content: "huazi\n"
dest: /var/www/html/index.html
notify: restart httpd
handlers:
- name: restart httpd #重启httpd
ansible.builtin.service:
name: httpd
state: restarted
ignore_errors
ignore_errors: yes
表示当该任务执行失败时,忽略当前任务,继续向下执行
[student@workstation control-flow]$ vim plalbook.yml
---
- name: restart http service
hosts: servera.lab.example.com
tasks:
- name: httpd installed
ansible.builtin.dnf:
name: http #将服务名写错
state: present
ignore_errors: yes #当该任务执行失败后,继续向下执行
- name: httpd started
ansible.builtin.service:
name: httpd
state: started
enabled: true
- name: reset index.html
ansible.builtin.copy:
content: "huazi\n"
dest: /var/www/html/index.html
notify: restart httpd
handlers:
- name: restart httpd
ansible.builtin.service:
name: httpd
state: restarted
[student@workstation control-flow]$ ansible-navigator run -m stdout plalbook.yml
PLAY [restart http service] ****************************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
TASK [httpd installed] *********************************************************
fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "failures": ["No package http available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring
TASK [httpd started] ***********************************************************
ok: [servera.lab.example.com]
TASK [reset index.html] ********************************************************
ok: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
block,rescue,always
- 如果
block
里面的任务成功执行,则忽略
后面的rescue
里面的任务,但不
影响always
里面的任务 block,rescue,always
在tasks
参数的下一级
,但在模块
的上一级
。block,rescue,always
有一个同级
的name参数
,用于描述任务
changed_when
changed_when: false
表示实际上远程主机没有被更改
包含文件与导入文件
- 包含文件是一个
动态操作
,在playbook
运行期间,ansible
会在内容到达时
处理所包含的内容 - 导入文件是一个
静态操作
,在运行开始之前
,ansible
在最初解析playbook
时预处理导入
的内容
import_tasks
import_playbook
include_tasks
[student@workstation projects-file]$ cat playbook.yml
---
- name: confiure web server
hosts: servera.lab.example.com
tasks:
- name: include the environment task file
include_tasks: tasks/environment.yml
vars:
package: httpd
service: httpd
- name: import the
import_tasks: tasks/firewall.yml
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
rule:
- http
- https
name: import the placeholder
import_tasks: tasks/placeholder.yml
vars:
file: /var/www/html/index.html
- name: import test play
import_playbook: plays/test.yml
vars:
url: 'http://servera.lab.example.com'
角色
-
角色
本质上也是一个目录
-
简单来讲,
roles
就是通过分别将变量、文件、任务、模块及处理器
放置于单独的目录
中,并可以便捷地include
它们
Roles 内各目录含义解释:
files
:用来存放由copy
模块或script
模块调用的文件templates
:用来存放jinjia2
模板,template
模块会自动在此目录中寻找jinjia2
模板文件tasks
:此目录应当包含一个main.yml
文件,用于定义此角色的任务列表,此文件可以使用include
包含其它的位于此目录的task
文件handlers
:此目录应当包含一个main.yml
文件,用于定义此角色中触发条件时执行的动作vars
:此目录应当包含一个main.yml
文件,用于定义此角色用到的变量defaults
:此目录应当包含一个main.yml
文件,用于为当前角色设定默认变量meta
:此目录应当包含一个main.yml
文件,用于定义此角色的特殊设定及其依赖关系
[student@workstation role-create]$ ansible-galaxy init myvhost #在当前目录下创建myvhost角色
[student@workstation role-create]$ ll
drwxr-xr-x. 10 student student 154 Aug 17 17:21 myvhost
在Ansible
中,ansible-galaxy
命令是一个用于管理Ansible
角色的工具。通过该命令,你可以安装、删除、列出或搜索Ansible Galaxy
中的角色。在你提供的命令中:
ansible-galaxy role install -r roles/requirements.yml -p roles/
这个命令执行了以下操作:
ansible-galaxy role install
:这是安装角色的子命令。-r roles/requirements.yml
:这个选项指定了一个包含角色需求列表的文件(YAML格式)。Ansible Galaxy
将从这个文件中读取需要安装的角色
及其版本(如果指定了的话)。这里的文件路径是roles/requirements.yml
,意味着Ansible将在当前目录的roles
子目录下查找这个文件。-p roles/
:这个选项指定了安装角色的目标目录。在这个例子中,所有安装的角色都将被放置在当前目录的roles
子目录下。这是一个很好的做法,因为它可以帮助你组织和管理你的项目中的Ansible角色。
列出角色
[devops@workstation ansible]$ ansible-galaxy role list
# /home/devops/ansible/roles
- balancer, (unknown version)
- phpinfo, (unknown version)
运行角色
[devops@workstation ansible]$ vim selinux.yml
---
- name: setup selinux policy
hosts: all
vars:
selinux_policy: targeted
selinux_state: enforcing
roles: #任务在角色中,所以在playbook中只需设定任务需要的vars参数和指定roles
- redhat.rhel_system_roles.selinux
[devops@workstation ansible]$ ansible-navigator run -m stdout selinux.yml
安装collection
ansible-galaxy collection install 包路径 --force
列出colection
ansible-galaxy collection list
pre_tasks
post_tasks
pre_tasks
:在playbook
执行tasks
之前执行post_tasks
:在所有tasks
执行后执行- 与
tasks
具有相同的性质
总结
when
中的变量
不用{{ }}
包裹debug
中var
参数的变量
不用{{ }}
包裹.j2
文件中的变量需要用{{}}
包裹firewalld
模块和mount
模块用的是ansible.posix
集合filesystem
模块和parted
模块和lvol
模块和lvg
模块用的是community.general
集合其他常用模块
用的是ansible.builtin
集合