ansible-playbook
使用playbook的好处
-
官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
-
特点
- 易读的编排语言
- 适合配置管理和应用部署
- 非常适合复杂的工作
playbook实例
- 编写playbook和测试配置
$ mkdir ansible-demo && cd ansible-demo/
$ vim site.conf #配置文件
server {
listen 80;
server_name www.cropy.cn;
location / {
root /var/www/html/;
index index.html;
}
}
$ vim nginx.yml
---
- hosts: webservers
vars:
hello: Ansible
tasks:
- name: Add Nginx Repo
yum_repository:
name: nginx
description: nginx repo
baseurl: http://nginx.org/packages/centos/7/$basearch/
gpgcheck: no
enabled: 1
- name: install nginx
yum:
name: nginx
state: latest
- name: copy nginx config
copy:
src: ./site.conf
dest: /etc/nginx/conf.d/site.conf
- name: start nginx
service:
name: nginx
state: started
enabled: yes
- name: create wwwroot directory
file:
dest: /var/www/html
state: directory
- name: create test page
shell: "echo {{ hello }} > /var/www/html/index.html"
$ ansible-playbook nginx.yml --syntax-check #语法检查&调试
$ ansible-playbook nginx.yml #部署
yaml 配置文件写法
- 开始以
---
开始 - 不支持制表符,缩进两个空格
- 缩进代表层级关系
#
代表注释,不执行
handles
- 变更时执行操作
---
- hosts: webservers
gather_facts: no
tasks:
- name: copy nginx config
copy:
src: ./site2.conf
dest: /etc/nginx/conf.d/site2.conf
notify:
- reload nginx
handlers:
- name: reload nginx
service: name=nginx state=reloaded
任务控制
- tags: 根据标签执行任务
$ vim nginx.yml
---
- hosts: webservers
vars:
hello: Ansible
tasks:
- name: Add Nginx Repo
yum_repository:
name: nginx
description: nginx repo
baseurl: http://nginx.org/packages/centos/7/$basearch/
gpgcheck: no
enabled: 1
tags: addRepo
- name: install nginx
yum:
name: nginx
state: latest
tags: installNginx
- name: copy nginx config
copy:
src: ./site.conf
dest: /etc/nginx/conf.d/site.conf
- name: start nginx
service:
name: nginx
state: started
- name: create wwwroot directory
file:
dest: /var/www/html
state: directory
- name: create test page
shell: "echo {{ hello }} > /var/www/html/index.html"
tags:
- addHtml
- addTest
$ ansible-playbook nginx.yml --tags "addRepo" #指定tags
$ ansible-playbook nginx.yml --tags "addRepo,installNginx"
$ ansible-playbook nginx.yml --skip-tags "addRepo,installNginx"
debug信息打印
$ vim debug.yml
---
- hosts: webservers
gather_facts: no
vars:
hello: Ansible
tasks:
- name: debug message
debug: msg={{ hello }}
$ ansible-playbook debug.yml
案例
- 自动部署tomcat
$ vim tomcat.yml
---
- hosts: webservers
gather_facts: no
vars:
tomcat_version: 8.5.56
tomcat_install_dir: /usr/local
tasks:
- name: install jdk
yum: name=java-1.8.0-openjdk state=present
- name: Download tomcat
get_url: url=http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz dest=/tmp
- name: unarchive tomcat-{{ tomcat_version }}.tar.gz
unarchive:
src: /tmp/apache-tomcat-{{ tomcat_version }}.tar.gz
dest: "{{ tomcat_install_dir }}"
copy: no
- name: start tomcat
shell: cd {{ tomcat_install_dir }} &&
mv apache-tomcat-{{ tomcat_version }} tomcat8 &&
cd tomcat8/bin && nohup ./startup.sh &
$ ansible-playbook tomcat.yml --syntax-check #语法检查
$ ansible-playbook tomcat.yml
playbook变量定义与使用
命令行定义使用变量
$ ansible-playbook nginx/nginx.yml --list-tags
$ ansible-playbook nginx/nginx.yml --list-tasks
$ vim demo1.yml
---
- hosts: webservers
gather_facts: no
remote_user: root
tasks:
- name: test var
debug: msg="{{ work_dir }}"
$ ansible-playbook demo1.yml -e work_dir="/root/dadda" #-e指定变量
inventory中定义变量
$ mkdir /etc/ansible/group_vars
$ vim /etc/ansible/group_vars/webservers.yml
http_port: 8080
server_name: 222.baidu.com
$ vim /etc/ansible/hosts #去掉此处定义的vars
[webservers]
192.168.56.11 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s http_port=80
192.168.56.12 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s
192.168.56.13 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s
192.168.56.14 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s
在playbook中定义变量
vim demo2.yml
---
- hosts: webservers
gather_facts: no
vars:
- work_dir: /usr/local
- nginx_version: 1.18
tasks:
- name: create dir
shell: mkdir -p "{{ work_dir }}/{{ nginx_version }}"
注册变量
---
- hosts: webservers
gather_facts: no
vars:
- work_dir: /usr/local
- nginx_version: 1.18
tasks:
- name: create dir
shell: mkdir -p "{{ work_dir }}/{{ nginx_version }}"
- name: register var
command: date +%F_%T
register: datetime
- name: touch file
file: dest=/tmp/r_{{ datetime.stdout }} state=touch
系统信息变量
playbook文件复用
include&import的区别
- include: 在运行时导入
--list-tags
,--list-tasks
不会输出显示- 不能使用notify触发来自include内部处理程序名称(handlers)
- import: 在playbook解析时预先导入
- 不能与循环一起使用
- 将变量用于目标文件或者角色名称时,不能使用inventory中的变量
import_playbook
- 目录结构
├── hosts #主机文件
├── lnmp.yml #lnmp入口
├── lnmt.yml #lnmt入口
├── mysql.yml #mysql入口
├── nginx.yml #nginx入口
├── php.yml #PHP入口
└── tomcat.yml #tomcat入口
- 代码详情
$ cat hosts
[lnmp]
192.168.56.11
192.168.56.12
$ cat lnmp.yml
---
- import_playbook: nginx.yml
- import_playbook: mysql.yml
- import_playbook: php.yml
$ cat lnmt.yml
---
- import_playbook: nginx.yml
- import_playbook: mysql.yml
- import_playbook: tomcat.yml
$ cat mysql.yml
---
- hosts: lnmp
gather_facts: no
tasks:
- name: Install Mysql
debug: msg="install mysql..."
$ cat nginx.yml
---
- hosts: lnmp
gather_facts: no
tasks:
- name: Install Ngigx
debug: msg="install nginx..."
$ cat php.yml
---
- hosts: lnmp
gather_facts: no
tasks:
- name: Install PHP
debug: msg="install php..."
$ cat tomcat.yml
---
- hosts: lnmp
gather_facts: no
tasks:
- name: Install Tomcat
debug: msg="install tomcat..."
- 测试执行
$ ansible-playbook -i hosts lnmt.yml #部署lnmt
$ ansible-playbook -i hosts lnmp.yml #部署lnmp
include_tasks
- 目录结构
├── hosts #主机文件
├── main.yml #任务入口文件
├── task1.yml #task1
└── task2.yml #task2
- 代码详情
$ cat hosts
[lnmp]
192.168.56.11
192.168.56.12
$ cat main.yml
---
- hosts: lnmp
gather_facts: no
tasks:
- include_tasks: task1.yml
- include_tasks: task2.yml
$ cat task1.yml
---
- name: task1
debug: msg="task1"
$ cat task2.yml
---
- name: task2
debug: msg="task2"
- 测试执行
$ ansible-playbook -i hosts main.yml
控制语法
条件判断
- 实例一
$ vim if_case.yml
---
- hosts: webservers
gather_facts: yes
tasks:
- name: host 192.168.56.11 run this task
debug: msg={{ansible_default_ipv4.address}}
when: ansible_default_ipv4.address == '192.168.56.11'
$ ansible-playbook if_case.yml
- 实例二
$ vim demo2.yml
---
- hosts: webservers
tasks:
- name: Update Apache Version - yum
yum: name=httpd state=present
when: ansible_pkg_mgr == 'yum'
notify: restart httpd
- name: Update Apache Version -apt
apt: name=httpd state=present
when: ansible_pkg_mgr == 'apt'
notify: restart apache2
handlers:
- name: restart httpd
service: name=httpd state=restarted
- name: restart apache2
service: name=apache2 stste=restarted
$ ansible-playbook demo2.yml
循环语句
- 实例一
$ vim demo1.yml
---
- hosts: webservers
gather_facts: no
tasks:
- name: loop list
debug: msg={{ item }}
loop:
- one
- two
- three
$ ansible-playbook demo1.yml
使用场景: 循环序列,比如多个用户创建等
- 实例二
$ vim adduser.yml
---
- hosts: webservers
gather_facts: no
tasks:
- name: add user and group
user: name={{item.name}} group={{item.groups}} state=present
with_items:
- {name: 'zhangsan',groups: 'nginx'}
- {name: 'lisi', groups: 'nginx'}
Jinja2 模板语法
- 条件和循环
$ vim test.yml
---
- hosts: webservers
gather_facts: no
vars:
hello: Ansible
tasks:
- template: src=f.j2 dest=/tmp/f.j2
$ vim f.j2
{% set list=['a','b','c'] %}
{% set dict='{"zhangsan":23, "lisi": 19}' %}
{% for i in list %}
{% if i == 'b' %}
-> b
{% elif loop.index == 3 %}
-> 3
{% else %}
{{ i }}
{% endif %}
{% endfor %}
{{ hello }}
{% for key,value in dict.iteritems() %}
{{ key }} ====> {{ value }}
{% endfor %}
$ ansible-playbook test.yml
$ cat /tmp/f.j2
a
-> b
-> 3
Ansible
lisi ====> 23
zhangsan ====> 19
- nginx配置文件管理案例
$ cat site.j2
upstream {{ server_name }} {
{% set list=[10,12,15,18] %}
upstream {{ server_name }} {
{% for i in list %}
server 192.168.56.{{ i }}:80;
{% endfor %}
}
server {
listen {{ listen_port }};
server_name {{ server_name }};
location / {
root /var/www/html/;
index index.html;
}
}
$ cat add_config.yml
---
- hosts: webservers
gather_facts: no
vars:
listen_port: 80
server_name: www.cropy.com
tasks:
- name:
template: src=./site.j2 dest=/etc/nginx/conf.d/site.conf
notify: restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
$ ansible-playbook add_config.yml