Ansible的脚本
一、playbook(剧本)
1、playbook的组成
1.1 tasks(任务):每一个tasks就是一个模快
1.2 variables(变量):存储和传递数据,可以自定义,也可以是全局变量,也可以是脚本外传参
1.3 templates(模版):用于生成配置文件和多任务的编排
1.4 handlers(处理器):满足某些条件时触发的操作,一般用于重启等操作
1.5 roles(角色):组织和封装剧本的过程,角色可以把任务,变量,模版,处理器,组合成一个可用单元
语法:yaml语法
注意格式和缩进(重要!!!)------以安装http为例
2、安装httpd
yaml
vim test1.yaml # 在opt目录下创建一个yaml脚本
- name: frist play
# 定义剧本名称,可不写
gather_facts: false
# 表示在执行剧本之前是否收集目标主机的信息,false表示不收集,可以加快执行速度,如果不写默认收集
hosts: 192.168.100.13
# 指定目标主机,可以是组名,也可以是ip地址
remote_user: root
# 在目标主机执行的用户名
tasks:
- name: test connection
# 定义一个任务的名称,可以自定义
ping:
# 表示ping模块
- name: close selinux
command: '/sbin/setenforce 0'
ignore_errors: True
# 如果在任务执行中,返回码非0表示报错,tasks就会停止;ignore_errors: True则会忽略错误,继续执行下一个任务
- name: close firewalld
service: name=firewalld state=stopped
# 调用service模块,关闭防火墙
- name: install httpd
yum: name=httpd state=latest
# latest表示安装当前库中最新版本的软件
- name: interview
shell: echo "this is httpd" > /var/www/html/index.html
# 执行shell模块,修改默认访问页面
notify: restart httpd
# ansible在执行完任务之后,并不是立即执行重启,通过notify指令对应的名称传给触发器,让触发器在任务的最后执行重启,避免在任务中多次执行重启,影响执行的效率
handlers:
- name: restart httpd
service: name=httpd state=restarted
wq!
ansible-playbook test1.yaml # 运行
3、安装nginx
要求:安装方式为yum,传一个配置文件到目标主机,修改默认端口为8080,访问页面内容为this is nginx
(1)修改端口
bash
(1)ansible主机yum安装nginx
yum -y install nginx
(2)改配置文件
cd /etc/nginx
cp nginx.conf /opt
vim nginx.conf
set nu
39 listen 8080; 改端口
40 #listen [::]:80; 注释
wq!
(2)创建yaml文件
yaml
vim nginx.yaml
- name: frist play
gather_facts: false
hosts: 192.168.100.13
remote_user: root
tasks:
- name: test connection
ping:
- name: close selinux
command: '/sbin/setenforce 0'
ignore_errors: True
- name: close firewalld
service: name=firewalld state=stopped
- name: install nginx
yum: name=nginx state=latest
- name: interview
shell: echo "this is nginx" > /usr/share/nginx/index.html
- name:
copy: 'src=/opt/nginx.conf dest=/etc/nginx'
notify: restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted
wq!
ansible-playbook nginx.yaml # 运行
4、定义变量和引用变量(传参)
脚本当中定义,以及脚本外传参
yaml
(1)脚本定义
vim test2.yaml
- name: second play
hosts: 192.168.100.14
remote_user: root
vars:
groupname: mysql
username: nginx1
# 定义变量
tasks:
- name: create group
group:
name: "{{ groupname }}"
system: yes
gid: 306
- name: create user
user:
name: "{{ username }}"
uid: 306
group: "{{ groupname }}"
wq!
ansible-playbook test2.yaml
test4
cat /etc/group # 创建mysql组,uid号等于306
cat /etc/passwd # 创建nginx1用户,uid和gid为306
test4
groupdel mysql # 删除mysql组
userdel nginx # 删除nginx1用户
(2)外部传参
ansible-playbook test2.yaml -e 'groupname=test1 username=test2' # 传参,外部的优先级大于内部的
test4
cat /etc/group # 创建test1组,uid号等于306
cat /etc/passwd # 创建test2用户,uid和gid为306
(3)切换用户
- name: second play
hosts: 192.168.100.14
remote_user: dn
become: yes
# 先用普通用户执行,但是需要切换到其他的用户,例如切换到管理员
become_user: root
其他部分和上面test2.yaml保持一致
wq!
5、ansible-playbook命令补充
bash
(1)检查语法是否正确
ansible-playbook test2.yaml --syntax-check
(2)检查脚本有几个任务
ansible-playbook test2.yaml --list-task
(3)检查对哪些主机生效
ansible-playbook test2.yaml --list-hosts
(4)指定对哪个任务开始运行
ansible-playbook test2.yaml --start-at-task='create user' -e 'username=test2 groupname=test1'
6、在脚本中实现条件判断
语法:when,满足条件的主机执行,不满足跳过
yaml
vim test3.yaml
- name: this is if
hosts: all
remote_user: root
tasks:
- name: test when
debug: msg='条件满足'
# debug相当于echo echo'条件满足'
when: ansible_default_ipv4.address == '192.168.100.14'
wq!
ansible-playbook test3.yaml # 运行
when: ansible_default_ipv4.address != '192.168.100.14' # 取反
7、迭代:循环结构
ansible有多种循环方式,一般都命名为with_items
,定义循环的内容
yaml
vim test4.yaml
# with_items 单循环输出
(1)
- name: item test
hosts: 192.168.100.13
remote_user: root
gather_facts: false
tasks:
- debug:
msg: "{{item}}"
with_items: [a,b,c,d]
# 输出item的值,with_items:a,b,c,d依次传入
wq!
ansible-playbook test4.yaml
(2)
- debug:
msg: "{{item}}"
with_items:
- [a,b,c,d]
- [1,2,3,4]
# 输出item的值,with_items:a,b,c,d,1,2,3,4依次传入
wq!
ansible-playbook test4.yaml
# with_list:以[]为整体输出
# with_together:把[]中的对应列,视为整体输出
# with_nested:把[]中各元素排列组合一遍
8、使用循环创建多个文件
要求:条件判断,主机的ip等于192.168.100.14,才会执行,一次性创建4个文件,/opt/a,/opt/b,/opt/c,/opt/d,循环,with_items
yaml
vim test5.yaml
(1)方法一
- name:
hosts: all
tasks:
- name: create files
when: ansible_default_ipv4.address == "192.168.100.14"
file:
path: "/opt/{{ item }}"
state: touch
with_items: [a,b,c,d]
(2)方法二
- name:
hosts: 192.168.100.14
gether_facts: false
vars:
test:
- /opt/test1
- /opt/test2
- /opt/test3
- /opt/test4
tasks:
- name: create mulu
file:
path: "{{item}}"
state: directory
with_items: "{{test}}"
wq!
ansible-playbook test5.yaml
二、tags机制
标签类型
always:设定标签名为always,除非指定跳过这个标签,否则该任务将始终会运行,即使指定了标签还会运行
never:始终不运行的任务,指定标签名never可以运行
debug:用于调试
setup:收集主机的信息
1、创建标签
yaml
vim test1.yaml
- hosts: 192.168.100.12
gather_facts: false
tasks:
- name: debug-test1
debug:
msg: "cow"
tags:
- debug
- name: always-test1
debug:
msg: "ALWays-RUN"
tags:
- always
- name: setup-test1
debug:
msg: "SETUP-1"
tags:
- setup
- name: never-test1
debug:
msg: "Never-run"
tags:
- never
wq!
ansible-playbook test1.yaml # 全部执行
ansible-playbook test1.yaml --tags=setup
# 从setup开始执行
ansible-playbook test1.yaml -skip--tags=always
# 跳过always不执行
ansible-playbook test1.yaml --tags="debug","setup"
# 运行
2、自定义标签
yaml
vim test2.yaml
- hosts: 192.168.100.12
remote_user: root
tasks:
- name: fuzhiwenjian
copy: src=/etc/hosts dest=/opt/hosts
tags:
- zlm
- name: touch file
file: path=/opt/test1 state=touch
tags:
- hpc
wq!
ansible-playbook test2.yaml --tags=hpc
3、模版
对应用的配置文件进行初始化,templates模版,Jinja组件,把编译过的模版文件传送给目标文件
yaml
cd /etc/httpd/conf
cp httpd.conf /opt/httpd.conf.j2
vim
set nu
42 Listen {{http_port}}
95 ServerName {{server_name}}
119 "{{root_dir}}"
wq!
vim /etc/ansible/hosts
set nu
wq!
vim test3/yaml
- hosts: 192.168.100.12
gather_facts: false
remote_user: root
vars:
- pg: httpd
- sv: httpd
tasks:
- name: install httpd
yum: name={{pg}}
- name: editon conf
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
handlers:
- name: restart httpd
service: name={{sv}} state=restarted
wq!
ansible-playbook test3.yaml
test2
cd /etc/
4、roles组合和配置复用
ansible为了层次化,结构化的组织playbook,使用roles(角色),通过层次化自动装载变量,任务和处理器等等。
通过roles把变量,任务和模块的文件单独放置在各个不同的目录中,通过roles一键编排
bash
cd /etc/ansible
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
yum -y install tree
tree
# roles:
------------------------------------------------------------------------------------------------------------
── httpd 角色名称,自定义
├── defaults 存放配置文件的目录,可以不写
├── files 存放copy模块或者script
├── handlers 存放处理器文件的目录
├── meta 保存角色源信息的文件
├── tasks 保存任务的文件
├── templates 保存模版的文件
└── vars 保存变量的文件
就是吧原来写在一个yaml的配置,分开---->不同目录---->保存在一个名字的yaml里面。执行是调用不同目录的同一个yaml文件。
main.yml(每个目录里面必须有,可以为空)
------------------------------------------------------------------------------------------------------------
cd task/httpd
vim main.yml
- name: install httpd
yum: name={{pkg}}
- name: start apach
service: name={{svc}} enabled=true state=started
cd vars
vim main.yml
pkg: httpd
sv
cd /etc/ansibe
vim site.yml
wq
ansible-playbook