文章目录
1.playbook简介及语法
- playbook是由一个或多个play组成的列表
- play的主要功能在于
将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色
。从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务 - Playbook核心元素
- Hosts 执行的远程主机列表
- Tasks 任务集
- Varniables 内置变量或自定义变量在playbook中调用
- Templates 模板,即使用模板语法的文件,比如配置文件等
- Handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码。
Playbook语法
-
playbook使用yaml语法格式,后缀可以是yaml,也可以是yml。
- 在单一一个playbook文件中,可以连续三个连子号(—)区分多个play。还有选择性的连续三个点好(…)用来表示play的结尾,也可省略。
- 次行开始正常写playbook的内容,一般都会写上描述该playbook的功能。
- 使用#号注释代码。
- 缩进必须统一,不能空格和tab混用。
- 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行实现的。
- YAML文件内容和Linux系统大小写判断方式保持一致,是区分大小写的,k/v的值均需大小写敏感
- k/v的值可同行写也可以换行写。同行使用:分隔。
- v可以是个字符串,也可以是一个列表
- 一个完整的代码块功能需要最少元素包括 name: task
执行方法及相关参数
执行方法: | ansible-playbook xxx.yml [参数] |
---|
–check-C | %检测
–syntax-check | %检check language(是否有语法错误)
–list-hosts | %检列出hosts
–list-tags | %检列出tag
–list-tasks | %检列出task
–limit | %检指定执行主机
-v -vv | %检现实过程
Playbook的核心组件
name %可选,建议使用,多用于说明
hosts %受控主机列表
tasks %任务,用与选择执行部分代码
Playbook中元素属性
- 主机与用户
在一个playbook开始时,最先定义的是要操作的主机和用户
---
hosts: 192.168.1.31
remote_user: root
- 在某一个tasks中定义要执行该任务的远程用户
tasks:
name: run df -h
remote_user: test
shell: name=df -h
还可以定义使用sudo授权用户执行该任务
tasks:
name: run df -h
sudo_user: test
sudo: yes
shell: name=df -h
- tasks任务列表
每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很清楚的辨别是属于哪一个task的,如果没有定义 name,action的值将会用作输出信息中标记特定的task。
每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks。
tasks:
- name: create new file
file: path=/tmp/test01.txt state=touch
- name: create new user
user: name=test001 state=present
- Handlers与Notify
很多时候当我们某一个配置发生改变,我们需要重启服务,(比如httpd配置文件文件发生改变了)这时候就可以用到handlers和notify了;
(当发生改动时)notify actions会在playbook的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify actions知会被触发一次;比如多个resources指出因为一个配置文件被改动,所以apache需要重启,但是重新启动的操作知会被执行一次。
2.playbook编写
1)安装配置httpd
%在虚拟机里
[devops@server1 ansible]$ vim ~/.vimrc
autocmd FileType yaml setlocal ai ts=2 sw=2 et
[devops@server1 ansible]$ ansible-doc dnf #看EXAMPLES
[devops@server1 ansible]$ ansible-doc firewalld #看EXAMPLES
[devops@server1 ansible]$ vim playbook.yml
通过ansible-playbook命令运行
格式:ansible-playbook <filename.yml> … [options]
[devops@server1 ansible]$ ansible-playbook --help
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml #查看错误
[devops@server1 ansible]$ ansible-playbook --list-hosts playbook.yml #主机名字
[devops@server1 ansible]$ ansible-playbook --list-tasks playbook.yml #全部任务
%server1
[devops@server1 ansible]$ ansible-playbook playbook.yml #执行,之后对象改成all一个任务在所有主机中跑完后,再跑下一任务,并行
2)安装配置httpd和mysql
[devops@server1 ansible]$ ansible-doc uri #看EXAMPLE
[devops@server1 ansible]$ ansible-doc myspl_user #看EXAMPLE
[devops@server1 ansible]$ ansible-doc myspl_db #看EXAMPLE创建数据库
[devops@server1 ansible]$ cat playbook.yml
---
- hosts: test
tasks:
- name: install apache
dnf:
name: httpd
state: present
- name: start apache
service:
name: httpd
state: started
enabled: yes
- name:
copy:
src: index.html
dest: /var/www/html/index.html
- name: start firewalld
service:
name: firewalld
state: started
enabled: yes
- name: accept http
firewalld:
service: http
permanent: yes
immediate: yes
state: enabled
- hosts: localhost
become: no
tasks:
- name: Check that a page returns a status 200
uri:
url: http://172.25.3.2
return_content: yes
- hosts: prod
tasks:
- name: install mariadb
dnf:
name:
- mariadb-server
- python3-PyMySQL
state: present
- name: start mariadb
service:
name: mariadb
state: started
enabled: yes
- name: accept 3306
firewalld:
service: mysql
permanent: yes
immediate: yes
state: enabled
- name: Example using login_unix_socket to connect to server
mysql_user:
name: root
password: westos
login_unix_socket: /var/lib/mysql/mysql.sock
- name: Removes anonymous user account for localhost
mysql_user:
login_user: root
login_password: westos
name: ''
host: localhost
state: absent
- name: Create a new database with name 'westos'
mysql_db:
login_user: root
login_password: westos
name: westos
state: present
- name: Create database user with name 'wxh' and password 'westos' with all database PRivileges
mysql_user:
login_user: root
login_password: westos
name: wxh
password: westos
priv: 'westos.*:ALL'
state: present
[devops@server1 ansible]$ ansible-playbook --list-hosts playbook.yml
[devops@server1 ansible]$ ansible-playbook --list-tasks playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml
#若有错误,在给密码的地方,可以使用
[devops@server1 ansible]$ ansible-playbook --start-at-task "Example using login_unix_socket to connect to server" playbook.yml
[devops@server1 ansible]$ vim playbook.yml
#改变的地方
- name: Example using login_unix_socket to connect to server
mysql_user:
name: root
password: westos
login_unix_socket: /var/lib/mysql/mysql.sock
tags: mysql #定义标签
[devops@server1 ansible]$ ansible-playbook -t mysql playbook.yml #只跑标签那部分
- name: Example using login_unix_socket to connect to server
mysql_user:
name: root
password: westos
login_user: root
login_password: westos
tags: mysql
在server3中测试mariadb:
3)httpd和mysql和测试页分开
[devops@server1 ansible]$ cp playbook.yml webserver.yml
[devops@server1 ansible]$ cp playbook.yml database.yml
[devops@server1 ansible]$ ls
ansible.cfg database.yml hosts index.html playbook.yml webserver.yml
[devops@server1 ansible]$ vim playbook.yml
[devops@server1 ansible]$ vim webserver.yml
[devops@server1 ansible]$ vim database.yml
[devops@server1 ansible]$ cp playbook.yml task.yml
[devops@server1 ansible]$ vim task.yml
4)变量
[devops@server1 ansible]$ cp playbook.yml task.yml
[devops@server1 ansible]$ cat task.yml
---
- name: Check that a page returns a status 200
uri:
url: "http://172.25.3.2:{{ http_port }}"
return_content: yes
status_code: 200
register: result
- debug:
msg: "test ok"
[devops@server1 ansible]$ vim webserver.yml
[devops@server1 ansible]$ ansible-playbook --list-tasks webserver.yml
[devops@server1 ansible]$ ansible-doc debug
[devops@server1 ansible]$ scp server2:/etc/httpd/conf/httpd.conf .
[devops@server1 ansible]$ ls
ansible.cfg database.yml hosts httpd.conf index.html playbook.yml task.yml webserver.yml
[devops@server1 ansible]$ vim webserver.yml
[devops@server1 ansible]$ cp httpd.conf httpd.conf.j2
[devops@server1 ansible]$ vim httpd.conf.j2
改为:
Listen {{ http_port }}
[devops@server1 ansible]$ ls
ansible.cfg hosts httpd.conf.j2 playbook.yml webserver.yml
database.yml httpd.conf index.html task.yml
[devops@server1 ansible]$ cat task.yml
---
- name: Check that a page returns a status 200
uri:
url: "http://172.25.3.2:{{ http_port }}"
return_content: yes
status_code: 200
register: result
- debug:
msg: "test ok"
%三个变量web_pkg: httpd;web_svc: httpd;http_port: 80
[devops@server1 ansible]$ vim webserver.yml
[devops@server1 ansible]$ ansible-playbook webserver.yml #运行成功
5)作apache的认证
[root@server2 conf]# htpasswd -c /etc/httpd/conf/htpasswd wxh #创建apache认证用户
New password: westos
Re-type new password: westos
Adding password for user wxh
[root@server2 conf]# ll
total 32
-rw-r--r--. 1 root root 42 Dec 27 15:13 htpasswd
-rw-r--r--. 1 root root 11899 Dec 2 2019 httpd.conf
-rw-r--r--. 1 root root 13064 Dec 2 2019 magic
[root@server2 conf]# cd /var/www/html/
[root@server2 html]# ls
index.html
[root@server2 html]# vim .htaccess
[root@server2 html]# cat .htaccess
AuthType Basic
AuthName "westos auth"
AuthUserFile /etc/httpd/conf/htpasswd
require valid-user
%在server1中:
[devops@server1 ansible]$ scp server2:/etc/httpd/conf/htpasswd .
htpasswd 100% 42 40.6KB/s 00:00
[devops@server1 ansible]$ ls
ansible.cfg hosts httpd.conf index.html task.yml
database.yml htpasswd httpd.conf.j2 playbook.yml webserver.yml
[devops@server1 ansible]$ scp server2:/var/www/html/.htaccess .
.htaccess 100% 95 94.0KB/s 00:00
[devops@server1 ansible]$ ls
ansible.cfg hosts httpd.conf index.html task.yml
database.yml htpasswd httpd.conf.j2 playbook.yml webserver.yml
[devops@server1 ansible]$ l.
. .. .htaccess
[devops@server1 ansible]$ vim webserver.yml
[devops@server1 ansible]$ vim httpd.conf.j2
改为All
AllowOverride All
[devops@server1 ansible]$ cat task.yml
---
- name: Check that a page returns a status 200
uri:
url: "http://172.25.3.2:{{ http_port }}"
user: wxh
password: westos
return_content: yes
status_code: 200
register: result
- debug:
var: result
[devops@server1 ansible]$ ansible-playbook webserver.yml #如下图,运行成功
6)交互式
%交互式
[devops@server1 ansible]$ cat task.yml
---
- hosts: localhost
vars:
http_port: 80
vars_prompt:
- name: username
prompt: What is your username?
private: no
- name: password
prompt: What is your password?
become: no
tasks:
- name: Check webserver
uri:
url: "http://172.25.3.2:{{ http_port }}"
user: "{{ username }}"
password: "{{ password }}"
return_content: yes
status_code: 200
register: result
- debug:
var: result
[devops@server1 ansible]$ vim webserver.yml
最后一行加上:
- import_playbook: task.yml
[devops@server1 ansible]$ ansible-playbook webserver.yml #运行结果如下
7)事实变量
%事实变量,必考点
%不同的主机部署不同的服务
[devops@server1 ansible]$ ansible test -m setup | less #查看事实变量信息
[devops@server1 ansible]$ cat playbook2.yml
---
- hosts: all
tasks:
- name: install apache
dnf:
name: httpd
state: present
when: ansible_hostname == "server2"#判断,只在server2上操作
- name: install mariadb
dnf:
name: mariadb-server
state: present
when: ansible_hostname == "server3"
[devops@server1 ansible]$ ansible-playbook --list-hosts playbook2.yml
[devops@server1 ansible]$ ansible-playbook playbook2.yml
[devops@node1 ansible]$ vim webserver.yml
修改- hosts:all
- name: create index.html
- name: create index.html
copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
注释tasks引用
[devops@node1 ansible]$ vim httpd.conf.j2 #取消交互式
修改 AllowOverride None
[devops@server1 ansible]$ ansible-playbook webserver.yml
[devops@node1 ansible]$ curl 10.4.17.242
node2
[devops@node1 ansible]$ curl 10.4.17.243
node3
%让不同的主机监控
%在每个主机上生成一个文件,记录每个主机的信息
[devops@node1 ansible]$ vim playbook3.yml
[devops@node1 ansible]$ vim hostinfo.j2
hostname: {{ ansible_facts['hostname'] }}
ip: {{ ansible_facts["enp1s0"]["ipv4"]["address"] }}
DNS: {{ ansible_facts['dns']['nameservers'][-1] }}
vda1: {{ ansible_facts['devices']['vda']['partitions']['vda1']['size'] }}
kernel: {{ ansible_facts['kernel'] }}
[devops@node1 ansible]$ vim httpd.conf.j2
Listen {{ ansible_facts["enp1s0"]["ipv4"]["address"] }}:{{ http_port }}
%批量创建用户
%循环字典的key,用item.user,item.passwd
[devops@node1 ansible]$ cat user.yml
---
- hosts: test
# vars:
# passwd: westos
tasks:
- name: create users
user:
name: "{{ item.user }}"
password: "{{ item.passwd | password_hash('sha512') }}"
loop:
- { user: 'user1', passwd: '123' }
- { user: 'user2', passwd: '456' }
- { user: 'user3', passwd: '789' }
[devops@node1 ansible]$ ansible-playbook user.yml
%增加安全性,建立数组形式的文件userlist
[devops@node1 ansible]$ cat user.yml
---
- hosts: test
vars_files:
- userlist.yml
tasks:
- name: create users
user:
name: "{{ item.user }}"
password: "{{ item.passwd | password_hash('sha512') }}"
loop: "{{ userlist }}"
[devops@node1 ansible]$ cat userlist.yml
---
userlist:
- user: 'user1'
passwd: '123'
- user: 'user2'
passwd: '456'
- user: 'user3'
passwd: '789'
[devops@node1 ansible]$ ansible-vault --help
[devops@node1 ansible]$ ansible-vault encrypt userlist.yml #给文件加密
New Vault password: westos
Confirm New Vault password: westos
Encryption successful
[devops@node1 ansible]$ ansible-vault view userlist.yml #查看
Vault password: westos
[devops@node1 ansible]$ ansible-vault edit userlist.yml #编辑
[devops@server1 ansible]$ ansible-playbook user.yml --ask-vault-pass #带密码跑user.yml