1. 脚本管理
为了避免重复输入命令,Ansible提供脚本功能。Ansible脚本的名字叫Playbook,使用的是YAML的格式,文件以yml结尾。
执行脚本语法
ansible-playbook deploy.yml
例子
deploy.yml的功能为web主机部署apache, 其中包含以下部署步骤:
- 安装apache包;
- 拷贝配置文件httpd,并保证拷贝文件后,apache服务会被重启;
- 拷贝默认的网页文件index.html;
- 启动apache服务;
playbook deploy.yml包含下面几个关键字,每个关键字的含义:
hosts:为主机的IP,或者主机组名,或者关键字all
remote_user: 以哪个用户身份执行。
vars: 变量
tasks: playbook的核心,定义顺序执行的动作action。每个action调用一个ansbile module。
action 语法: module: module_parameter=module_value
常用的module有yum、copy、template等,module在ansible的作用,相当于bash脚本中yum,copy这样的命令。
handers: 是playbook的event,默认不会执行,在action里触发才会执行。多次触发只执行一次.
---
- hosts: web
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: Write the configuration file
template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart apache
- name: Write the default index.html file
template: src=templates/index.html.j2 dest=/var/www/html/index.html
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
上面的deploy.yml格式转化为json格式为:
[
{
"hosts": "web",
"vars": {
"http_port": 80,
"max_clients": 200
},
"remote_user": "root",
"tasks": [
{
"name": "ensure apache is at the latest version",
"yum": "pkg=httpd state=latest"
},
{
"name": "Write the configuration file",
"template": "src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf",
"notify": [
"restart apache"
]
},
{
"name": "Write the default index.html file",
"template": "src=templates/index.html.j2 dest=/var/www/html/index.html"
},
{
"name": "ensure apache is running",
"service": "name=httpd state=started"
}
],
"handlers": [
{
"name": "restart apache",
"service": "name=httpd state=restarted"
}
]
}
]
1.1 play/playbook
Playbook是指一个可被ansible执行的yml文件,基本格式:
---
- hosts: web
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
在一个Playbook文件中还可以有针对两组server进行不同的操作,例如给web安装http服务器,和给lb安装mysql放在一个文件中:
---
#安装apache的play
- hosts: web
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
# 安装mysql server的play
- hosts: lb
remote_user: root
tasks:
- name: ensure mysqld is at the latest version
yum: pkg=mariadb state=latest
上面例子中针对每一组server的所有操作就组成一个play,一般一个playbook中只包含一个play,所以不用太在意区分playbook与play。如果在有些ansible文档中提到play的概念,知道是怎么回事就可以了。
2 Module
bash无论在命令行上执行,还是bash脚本中,都需要调用cd、ls、copy、yum等命令;module就是Ansible的“命令”,module是ansible命令行和脚本中都需要调用的。常用的Ansible module有yum、copy、template等。
在bash,调用命令时可以跟不同的参数,每个命令的参数都是该命令自定义的;同样,ansible中调用module也可以跟不同的参数,每个module的参数也都是由module自定义的。
2.1 Module使用
-m后面接调用module的名字
-a后面接调用module的参数
例子:
#使用module copy拷贝管理员节点文件/etc/hosts到所有远程主机/tmp/hosts
$ ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
#使用module yum在远程主机web上安装httpd包
$ ansible web -m yum -a "name=httpd state=present"
2.2 Playbook脚本使用Module
playbook脚本中,tasks中的每一个action都是对module的一次调用。在每个action中:
冒号前面是module的名字
冒号后面是调用module的参数
---
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: ensure apache is running
service: name=httpd state=started
2.3 特性
- 像Linux中的命令一样,Ansible的Module既上命令行调用,也可以用在Ansible的脚本Playbook中。
- 每个Module的参数和状态的判断,都取决于该module的具体实现,可通过命令ansible-doc也可以查看module的用法
- Ansible提供一些常用功能的Module,同时Ansible也提供API,让用户可以自己写Module,使用的编程语言是Python。
2.4 常用module
调试和测试类的module
ping - ping一下你的远程主机,如果可以通过ansible成功连接,那么返回pong
debug - 用于调试的module,只是简单打印一些消息,有点像linux的echo命令。
文件类的module
copy - 从本地拷贝文件到远程节点
template - 从本地拷贝文件到远程节点,并进行变量的替换
file - 设置文件的属性
linux上常用的操作
user - 管理用户账户
yum - red hat系linux上的包管理
service - 管理服务
firewalld - 管理防火墙中的服务和端口
执行Shell命令
shell - 在节点上执行shell命令,支持$HOME和”<”, “>”, “|”, “;” and “&”
command - 在远程节点上面执行命令,不支持$HOME和”<”, “>”, “|”, “;” and “&”
ping
最常用的测试一个节点有没有配置好ssh连接的module。不过它可不是简单像linux命令中ping一下远程节点,而是首先检查下能不能SSH登陆,然后再检查下远程节点的python版本漫不满足要求,如果都满足则会返回成功pong。
ping不需要传入任何参数。因为ping是测试节点连接是不是通的,所以一般在命令行中使用的时候比在playbook的脚本中多
[root@controller ~]# ansible all -m ping
192.168.143.194 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
192.168.143.192 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
debug
打印输出信息,和linux上的echo命令很像
1.通过参数msg定义打印的字符串
msg中可以嵌入变量,下面的例子中注入了系统变量,ansible在执行playbook之前会收集一些比较常用的系统变量,在playbook中不需要定义直接就可以使用。
- debug:
msg: "System \{\{ inventory_hostname \}\} has gateway \{\{ ansible_default_ipv4.gateway \}\}"
执行结果:
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "System localhost has gateway 192.168.50.1"
}
- 通过参数var定义需要打印的变量
变量可以是系统变量,也可以是动态的执行结果,通过关键字regester注入到变量中。
- name: Display all variables/facts known for a host
debug:
var: hostvars[inventory_hostname]["ansible_default_ipv4"]["gateway"]
执行结果:
TASK [Display part of variables/facts known for a host] ************************
ok: [localhost] => {
"hostvars[inventory_hostname][\"ansible_default_ipv4\"][\"gateway\"]": "192.168.50.1"
}
copy
从当前的机器上copy静态文件到远程节点上,并且设置合理的文件权限。注意,copy module拷贝文件的时候,会先比较下文件的checksum,如果相同则不会拷贝,返回状态OK;如果不同才会拷贝,返回状态为changed。
- copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: foo
group: foo
mode: 0644
#利用mode设置权限可以是用数字,当然也可以是符号的形式”u=rw,g=r,o=r”和”u+rw,g-wx,o-rwx”
backup: yes
#backup参数为yes的时候,如果发生了拷贝操作,那么会先备份下目标节点上的原文件。当两个文件相同时,不会进行拷贝操作
file
file module设置远程值机上的文件、软链接(symlinks)和文件夹的权限,也可以用来创建和删除
1.改变文件的权限
mode参数可以直接赋值数字权限(必须以0开头),也可以赋值,还可以用来增加和删除权限。具体的写法见下面的代码:
- file:
path: /etc/foo.conf
owner: foo
group: foo
mode: 0644
#mode: "u=rw,g=r,o=r"
#mode: "u+rw,g-wx,o-rwx"
2.创建文件的软链接
注意这里面的src和sest参数的含义是和copy module不一样的,file module里面所操作的文件都是远程节点上的文件。
- file:
src: /file/to/link/to
dest: /path/to/symlink
owner: foo
group: foo
state: link
3.创建一个新文件
- file:
path: /etc/foo.conf
state: touch
mode: "u=rw,g=r,o=r"
4.创建新的文件夹
# create a directory if it doesn't exist
- file:
path: /etc/some_directory
state: directory
mode: 0755
user
user module可以增、删、改Linux远程节点的用户账户,并为其设置账户的属性。
1.增加user
增加账户johnd,并且设置uid为1040,设置用户的primary group为admin
- user:
name: johnd
comment: "John Doe"
uid: 1040
group: admin
创建账户james,并为james用户额外添加两个group
- user:
name: james
shell: /bin/bash
groups: admins,developers
append: yes
2.删除账户
- user:
name: johnd
state: absent
remove: yes
3.修改账户的属性
为账户jsmith创建一个 2048-bit的SSH key,放在~jsmith/.ssh/id_rsa
- user:
name: jsmith
generate_ssh_key: yes
ssh_key_bits: 2048
ssh_key_file: .ssh/id_rsa
为用户添加过期时间:
- user:
name: james18
shell: /bin/zsh
groups: developers
expires: 1422403387
yum
yum module是用来管理red hat系的Linux上的安装包的,包括RHEL,CentOS,和fedora 21一下的版本。fedora从版本22开始就使用dnf,推荐使用dnf module来进行安装包的操作。
1.从yum源上安装和删除包
- name: install the latest version of Apache
yum:
name: httpd
state: latest
2.安装指定版本的包
- name: install one specific version of Apache
yum:
name: httpd-2.2.29-1.4.amzn1
state: present
3.删除httpd包
- name: remove the Apache package
yum:
name: httpd
state: absent
4.从指定的repo testing中安装包
- name: install the latest version of Apache from the testing repo
yum:
name: httpd
enablerepo: testing
state: present
5.从yum源上安装一组包
- name: install the 'Development tools' package group
yum:
name: "@Development tools"
state: present
- name: install the 'Gnome desktop' environment group
yum:
name: "@^gnome-desktop-environment"
state: present
6.从本地文件中安装包
- name: install nginx rpm from a local file
yum:
name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
7.从URL中安装包
- name: install the nginx rpm from a remote repo
yum:
name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
service
开、关、重起、重载服务
- service:
name: httpd
state: started
- service:
name: httpd
state: stopped
- service:
name: httpd
state: restarted
- service:
name: httpd
state: reloaded
- service:
name: httpd
enabled: yes
- service:
name: network
state: restarted
args: eth0
firewalld
firewalld module为某服务和端口添加firewalld规则。firewalld中有正在运行的规则,和永久的规则,firewalld module都支持。
1.为服务添加firewalld规则
- firewalld:
service: https
permanent: true
state: enabled
- firewalld:
zone: dmz
service: http
permanent: true
state: enabled
2.为端口号添加firewalld规则
- firewalld:
port: 8081/tcp
permanent: true
state: disabled
- firewalld:
port: 161-162/udp
permanent: true
state: enabled
3.其它复杂的firewalld规则
- firewalld:
rich_rule: 'rule service name="ftp" audit limit value="1/m" accept'
permanent: true
state: enabled
- firewalld:
source: 192.0.2.0/24
zone: internal
state: enabled
shell
通过/bin/sh在远程节点上执行命令。如果一个操作你可以通过Module yum,copy操作实现,那么你不要使用shell或者command这样通用的命令module。因为通用的命令module不会根据具体操作的特点进行status的判断,所以当没有必要再重新执行的时候,它还是要重新执行一遍。
Command
在远程节点上执行命令。和Shell Module类似,不过不支持$HOME and operations like “<”, “>”, “|”, “;” and “&”。