Ansible

238 阅读17分钟

颜色说明

绿色: 代表被管理主机没有被修改
黄色: 代表被管理主机发生变更
红色: 代表出现故障

参数

--version 	# ansible 版本信息
-v 			# 显示详细信息
-i 			# 主机清单文件路径,默认在/etc/ansible/hosts
-m			# 使用的模块名称,默认使用command模块
-a 			# 使用的模块参数,模块的具体动作
-k  		# 提示输入ssh密码,而不使用基于ssh的密钥认证
-C 			# 模拟执行测试,但不会真的执行
-T 			# 执行命令的超时

example

hosts

[web]
192.168.101.28 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='111111'
192.168.101.15 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='111111'

执行

[root@localhost ~]# ansible web -m ping -i ./hosts 
192.168.101.28 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.101.15 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

可能会出现问题 host_key_checking


免密登录

# 生成公钥和私钥
ssh-keygen
# 把公钥匙拷贝到指定机器中
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.101.15
# 那么就可以免密登录15这台服务器了

# 此时 15 这台服务器的 /root/.ssh目录中的authorized_keys便会添加一条公钥
[root@localhost .ssh]# cat /root/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDK7KpTXRal9YQ5VlN8Hwav11ggYd6DEwEH2V3uWWJLb9F9xuwzIOpehapHmDgO7vRIzy8+5392mPdBkF+qsa3OOA7GK6gGPg6CDa0dUcfumo7QSkE+M8YfxefvIZGQXHSEDOHJnc2m/KPizus7K5bV0M3D9w0HxGGDbKaWBGQH2lt8gWAznvYaqV5wiHN6KCVd74Lz3DqHYLG74JRA5x3kVwDgGjEDH/0KNexQQsmQ9nG4suWp2JkDQBCaoEU3wtGQ1wf27QNmnrL5postrsbzzBX2zN7hHPIqh6XUBTzMEBJtyUtt5qrM/MlZFIO3pkcVz2g8yA3tUgRSOLyd+z6T root@localhost.localdomain

为主机命名

hosts

[web]
测试服务器 ansible_ssh_host=192.168.101.15
测试服务器2 ansible_ssh_host=192.168.101.28
[root@localhost ~]# ansible web -m ping -i ./hosts
测试服务器 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
测试服务器2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

ad-hoc

ansible-doc-l					# 查看所有模块说明
ansible-doc copy			# 查看指定模块方法
ansible-dock -s copy 	# 查看指定模块参数

常用模块

command					# 执行shell命令(不支持管道符等特殊字符)
shell						# 执行shell命令
script					# 执行shell脚本
yum_repository	#	配置yum仓库
yum							# 安装软件
copy						# 变更配置文件
file						# 创建文件或目录
service					# 启动与停止服务
mount						# 挂载设备
cron						# 定时任务
get_url					# 下载软件
firewalld				# 防火墙
selinux					# selinux

Example

Command模块

不能使用管道符等特殊字符

[root@zhangsan ~]# ansible web -m command -a 'df -h' -i ./hosts
192.168.101.15 | CHANGED | rc=0 >>
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   50G  3.2G   47G    7% /
devtmpfs                 1.9G     0  1.9G    0% /dev
tmpfs                    1.9G     0  1.9G    0% /dev/shm
tmpfs                    1.9G   18M  1.9G    1% /run
tmpfs                    1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/mapper/centos-home   46G   33M   46G    1% /home
/dev/sda1               1014M  145M  870M   15% /boot
tmpfs                    379M     0  379M    0% /run/user/0
overlay                   50G  3.2G   47G    7% /var/lib/docker/overlay2/bef255a75bec68c23cdc64b4ab841d45cee96266edd4607e6eea6ffc644639eb/merged
shm                       64M     0   64M    0% /var/lib/docker/containers/0195f9ca948a6689b4467b75d01ef014ce1db6f9c5835c24ee5de85670b1639b/mounts/shm
overlay                   50G  3.2G   47G    7% /var/lib/docker/overlay2/36db0f3cbe48e6cfda85a7ac485ec76b9c5abf673657e2dbd8511d13ec1f0cbe/merged
shm                       64M     0   64M    0% /var/lib/docker/containers/76ed696b5f68f18fde74590b308c6ff44f34e630ccb54372dd513cf47ee58d87/mounts/shm
[root@zhangsan ~]# ansible web -m command -a 'free -h' -i ./hosts
192.168.101.15 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           3.7G        764M        1.1G         17M        1.8G        2.6G
Swap:            0B          0B          0B

Shell模块

用来执行shell命令,可以使用管道符等特殊字符

[root@zhangsan ~]# ansible web -m shell -a 'ps aux | grep nginx' -i hosts
192.168.101.15 | CHANGED | rc=0 >>
root       757  0.0  0.0  20556  1560 ?        Ss   10月25   0:00 nginx: master process /usr/local/nginx/sbin/nginx -g daemon off;
nobody     792  0.0  0.0  21004  1560 ?        S    10月25   0:00 nginx: worker process
root     11535  0.0  0.1 123780  5956 ?        Ss   10月24   0:00 nginx: master process nginx
nginx    11865  0.0  0.1 124252  4444 ?        S    10月24   0:00 nginx: worker process
root     12705  0.0  0.0 113280  1208 pts/0    S+   13:55   0:00 /bin/sh -c ps aux | grep nginx
root     12707  0.0  0.0 112832   956 pts/0    S+   13:55   0:00 grep nginx

script模块

用来执行shell脚本

test.sh

#!/bin/bash
yum -y install vsftpd
[root@zhangsan ~]# ansible web -m script -a './test.sh' -i hosts
192.168.101.15 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.101.15 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.101.15 closed."
    ],
    "stdout": "已加载插件:fastestmirror\r\nDetermining fastest mirrors\r\n * base: mirrors.aliyun.com\r\n * extras: mirrors.aliyun.com\r\n * updates: mirrors.aliyun.com\r\n\rbase                                                     | 3.6 kB     00:00     \r\n\rdocker-ce-stable                                         | 3.5 kB     00:00     \r\n\repel                                                     | 4.7 kB     00:00     \r\n\rextras                                                   | 2.9 kB     00:00     \r\n\rkubernetes/signature                                     |  454 B     00:00     \r\n\rkubernetes/signature                                     | 1.4 kB     00:00 !!! \r\n\rupdates                                                  | 2.9 kB     00:00     \r\n正在解决依赖关系\r\n--> 正在检查事务\r\n---> 软件包 vsftpd.x86_64.0.3.0.2-27.el7 将被 安装\r\n--> 解决依赖关系完成\r\n\r\n依赖关系解决\r\n\r\n================================================================================\r\n Package          架构             版本                    源              大小\r\n================================================================================\r\n正在安装:\r\n vsftpd           x86_64           3.0.2-27.el7            base           172 k\r\n\r\n事务概要\r\n================================================================================\r\n安装  1 软件包\r\n\r\n总下载量:172 k\r\n安装大小:353 k\r\nDownloading packages:\r\n\rvsftpd-3.0.2-27.el7.x86_64.rpm                             | 172 kB   00:00     \r\nRunning transaction check\r\nRunning transaction test\r\nTransaction test succeeded\r\nRunning transaction\r\n\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [                              ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [######                        ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###########                   ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [##############                ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###############               ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [################              ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#####################         ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [######################        ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#######################       ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [########################      ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#########################     ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [##########################    ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###########################   ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [############################  ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [############################# ] 1/1\r  正在安装    : vsftpd-3.0.2-27.el7.x86_64                                  1/1 \r\n\r  验证中      : vsftpd-3.0.2-27.el7.x86_64                                  1/1 \r\n\r\n已安装:\r\n  vsftpd.x86_64 0:3.0.2-27.el7                                                  \r\n\r\n完毕!\r\n",
    "stdout_lines": [
        "已加载插件:fastestmirror",
        "Determining fastest mirrors",
        " * base: mirrors.aliyun.com",
        " * extras: mirrors.aliyun.com",
        " * updates: mirrors.aliyun.com",
        "",
        "base                                                     | 3.6 kB     00:00     ",
        "",
        "docker-ce-stable                                         | 3.5 kB     00:00     ",
        "",
        "epel                                                     | 4.7 kB     00:00     ",
        "",
        "extras                                                   | 2.9 kB     00:00     ",
        "",
        "kubernetes/signature                                     |  454 B     00:00     ",
        "",
        "kubernetes/signature                                     | 1.4 kB     00:00 !!! ",
        "",
        "updates                                                  | 2.9 kB     00:00     ",
        "正在解决依赖关系",
        "--> 正在检查事务",
        "---> 软件包 vsftpd.x86_64.0.3.0.2-27.el7 将被 安装",
        "--> 解决依赖关系完成",
        "",
        "依赖关系解决",
        "",
        "================================================================================",
        " Package          架构             版本                    源              大小",
        "================================================================================",
        "正在安装:",
        " vsftpd           x86_64           3.0.2-27.el7            base           172 k",
        "",
        "事务概要",
        "================================================================================",
        "安装  1 软件包",
        "",
        "总下载量:172 k",
        "安装大小:353 k",
        "Downloading packages:",
        "",
        "vsftpd-3.0.2-27.el7.x86_64.rpm                             | 172 kB   00:00     ",
        "Running transaction check",
        "Running transaction test",
        "Transaction test succeeded",
        "Running transaction",
        "",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [                              ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [######                        ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###########                   ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [##############                ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###############               ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [################              ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#####################         ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [######################        ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#######################       ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [########################      ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [#########################     ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [##########################    ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [###########################   ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [############################  ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64 [############################# ] 1/1",
        "  正在安装    : vsftpd-3.0.2-27.el7.x86_64                                  1/1 ",
        "",
        "  验证中      : vsftpd-3.0.2-27.el7.x86_64                                  1/1 ",
        "",
        "已安装:",
        "  vsftpd.x86_64 0:3.0.2-27.el7                                                  ",
        "",
        "完毕!"
    ]
}

Yum模块

name	
	httpd			# 指定要安装的软件包名称
	file://		# 指定本地安装路径(yum localinstall 本地rpm包)
	http://		# 指定yum源(从远程仓库获取)
	
state				# 指定使用yun的方法动作
	installed, present		# 安装软件包
	removed, absent				# 移除软件
	latest								# 安装最新软件包
安装
[root@zhangsan ~]# ansible web -m yum -a 'name=httpd state=present' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "changes": {
        "installed": [
            "httpd"
        ]
    },
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-93.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch           Version                        Repository    Size\n================================================================================\nInstalling:\n httpd         x86_64         2.4.6-93.el7.centos            base         2.7 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-2.4.6-93.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-93.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-93.el7.centos                                            \n\nComplete!\n"
    ]
}
卸载
[root@zhangsan ~]# ansible web -m yum -a 'name=httpd state=absent' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "changes": {
        "removed": [
            "httpd"
        ]
    },
    "msg": "",
    "rc": 0,
    "results": [
        "已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-93.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构           版本                          源             大小\n================================================================================\n正在删除:\n httpd         x86_64         2.4.6-93.el7.centos           @base         9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-93.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-93.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-93.el7.centos                                            \n\n完毕!\n"
    ]
}

Copy模块

src			# 源文件
dest		# 目标路径
backup	# 传输过去的文件进行备份
content	# 直接批量在被管理端文件中添加内容
group		# 指定文件属组信息
owner		# 指定文件属主信息
mode		# 文件权限

拷贝文件

[root@zhangsan ~]# ansible web -m copy -a 'src=/etc/passwd dest=/tmp/passwd_copy' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "8256a0b27707bf2ac7aef8c45335eee24854152e",
    "dest": "/tmp/passwd_copy",
    "gid": 0,
    "group": "root",
    "md5sum": "160858c4b4ac90155f7da05d396db308",
    "mode": "0644",
    "owner": "root",
    "size": 1007,
    "src": "/root/.ansible/tmp/ansible-tmp-1603190747.93-9270-39814859258206/source",
    "state": "file",
    "uid": 0
}
修改内容

内容会被替换

[root@zhangsan ~]# ansible web -m copy -a 'content="hello world" dest=/tmp/passwd_copy' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
    "dest": "/tmp/passwd_copy",
    "gid": 0,
    "group": "root",
    "md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3",
    "mode": "0755",
    "owner": "root",
    "size": 11,
    "src": "/root/.ansible/tmp/ansible-tmp-1603191296.79-9342-270551071927816/source",
    "state": "file",
    "uid": 0
}

File模块

path			# 远程主机目录或文件信息
recurse		# 递归授权
state
	directory			# 在被管理端创建目录
  touch					# 在远端创建文件
  link					# link或hand表示创建链接文件
  absent				# 删除文件或目录
  mode					# 设置文件或目录权限
  owner					# 设置文件或目录属主
  group					# 设置文件或目录属组
创建目录
[root@zhangsan ~]# ansible web -m file -a 'path=/tmp/test state=directory' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/tmp/test",
    "size": 6,
    "state": "directory",
    "uid": 0
}
删除目录
[root@zhangsan ~]# ansible web -m file -a 'path=/tmp/test state=absent' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "path": "/tmp/test",
    "state": "absent"
}

group模块

name			# 指定创建的组名
gid				# 指定组的gid
state
		absent	# 移除被管理端的组
		present	# 创建被管理段的组
创建组
[root@zhangsan ~]# ansible web -m group -a 'name=t1 state=present' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 1000,
    "name": "t1",
    "state": "present",
    "system": false
}
删除组
[root@zhangsan ~]# ansible web -m group -a 'name=t1 state=absent' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "name": "t1",
    "state": "absent"
}

user模块

uid					# 指定用户的uid
group				# 指定用户的组
groups			# 指定附加组
password		# 给用户添加密码(单引号)
shell				# 指定用户登录的shell
create_home	# 是否创建家目录
创建普通用户
[root@zhangsan ~]# ansible web -m user -a 'name=testuser shell=/bin/bash create_home=true' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 1000,
    "home": "/home/testuser",
    "name": "testuser",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1000
}
创建不能登录的用户
[root@zhangsan ~]# ansible web -m user -a 'name=testuser2 shell=/sbin/nologin create_home=false' -i ./hosts
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": false,
    "group": 1001,
    "home": "/home/testuser2",
    "name": "testuser2",
    "shell": "/sbin/nologin",
    "state": "present",
    "system": false,
    "uid": 1001
}

Selinux

关闭selinux

查看selinux状态

[root@zhangsan ~]# ansible web -m shell -a 'getenforce' -i ./hosts
192.168.101.15 | CHANGED | rc=0 >>
Enforcing

重启后生效

[root@zhangsan ~]# ansible web -m selinux -a 'state=disabled' -i ./hosts
[WARNING]: SELinux state temporarily changed from 'enforcing' to 'permissive'. State change will take effect next reboot.
192.168.101.15 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "configfile": "/etc/selinux/config",
    "msg": "Config SELinux state changed from 'enforcing' to 'disabled'",
    "policy": "targeted",
    "reboot_required": true,
    "state": "disabled"
}
[root@zhangsan ~]# ansible web -m shell -a 'getenforce' -i ./hosts
192.168.101.15 | CHANGED | rc=0 >>
Permissive

临时关闭

[root@zhangsan ~]# ansible web -m shell -a 'setenforce 0' -i ./hosts
192.168.101.15 | CHANGED | rc=0 >>

Setup模块

查看所有详细信息
[root@zhangsan ~]# ansible web -m setup -i ./hosts
192.168.101.15 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.101.15"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::30f3:dfc2:af2d:658a"
        ],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "12/12/2018",
        "ansible_bios_version": "6.00",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-957.el7.x86_64",
            "LANG": "en_US.UTF-8",
            "crashkernel": "auto",
            "quiet": true,
            "rd.lvm.lv": "centos/swap",
            "rhgb": true,
            "ro": true,
            "root": "/dev/mapper/centos-root"
        },
        "ansible_date_time": {
            "date": "2020-11-03",
            "day": "03",
            "epoch": "1604408353",
            "hour": "07",
            "iso8601": "2020-11-03T12:59:13Z",
            "iso8601_basic": "20201103T075913324409",
            "iso8601_basic_short": "20201103T075913",
            "iso8601_micro": "2020-11-03T12:59:13.324409Z",
            "minute": "59",
            "month": "11",
            "second": "13",
            "time": "07:59:13",
            "tz": "EST",
            "tz_offset": "-0500",
            "weekday": "星期二",
            "weekday_number": "2",
            "weeknumber": "44",
            "year": "2020"
        },
        "ansible_default_ipv4": {
            "address": "192.168.101.15",
            "alias": "ens192",
            "broadcast": "192.168.101.255",
            "gateway": "192.168.101.1",
            "interface": "ens192",
            "macaddress": "00:0c:29:c3:a7:8e",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "192.168.101.0",
            "type": "ether"
        },
......
获取IP地址
[root@zhangsan ~]# ansible web -m setup -a 'filter=ansible_default_ipv4' -i ./hosts
192.168.101.15 | SUCCESS => {
    "ansible_facts": {
        "ansible_default_ipv4": {
            "address": "192.168.101.15",
            "alias": "ens192",
            "broadcast": "192.168.101.255",
            "gateway": "192.168.101.1",
            "interface": "ens192",
            "macaddress": "00:0c:29:c3:a7:8e",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "192.168.101.0",
            "type": "ether"
        },
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

Playbook

example.yml

- hosts: web
  tasks:
    - name: touch a file
      file: name=/tmp/hello state=touch
检查语法
[root@zhangsan ~]# ansible-playbook --syntax-check example.yml -i ./hosts

playbook: example.yml
模拟执行(不是真的执行)
[root@zhangsan ~]# ansible-playbook -C example.yml -i ./hosts

PLAY [web] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [touch a file] *************************************************************************************************************************
ok: [192.168.101.15]

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

执行playbook
[root@zhangsan ~]# ansible-playbook example.yml -i ./hosts

PLAY [web] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [touch a file] *************************************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Playbook定义变量

example.yml

- hosts: web
  vars: 
    filename: t1 # 定义变量
  tasks:
    - name: touch a file
      file: name=/tmp/{{filename}} state=touch
使用变量
[root@zhangsan ~]# ansible-playbook example.yml -i ./hosts

PLAY [web] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [touch a file] *************************************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

传参

example.yml

- hosts: web
  tasks:
    - name: touch a file
      file: name=/tmp/{{filename}} state=touch

--extra-vars filename=t2

[root@zhangsan ~]# ansible-playbook -C example.yml --extra-vars 'filename=t2' -i ./hosts

PLAY [web] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [touch a file] *************************************************************************************************************************
ok: [192.168.101.15]

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

主机组中定义变量

hosts

[web]
192.168.101.15

[web:vars]
filename=t3

example.yml

- hosts: all
  tasks:
    - name: touch a file
      file: name=/tmp/{{filename}} state=touch
[root@zhangsan ~]# ansible-playbook example.yml -i ./hosts

PLAY [all] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [touch a file] *************************************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

变量传参优先级

  1. extra-vars 外置传参的优先级最高 [所有执行主机都生效]
  2. 定义在yml文件中的优先级第二 [所有主机都生效]
  3. hosts 文件中定义的变量优先级最低 [当前主机组定义会生效]

Playbook注册变量

注册变量: register关键字可以存储指定命令的输出结果到一个自定义变量中

example.yml

- hosts: web
  tasks:
    - name:
      shell: netstat -luntp
      register: test

    - name: get listen port
      debug: msg={{test.stdout_lines}}
[root@zhangsan ~]# ansible-playbook example.yml -i ./hosts

PLAY [web] **********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [192.168.101.15]

TASK [shell] ********************************************************************************************************************************
changed: [192.168.101.15]

TASK [get listen port] **********************************************************************************************************************
ok: [192.168.101.15] => {
    "msg": [
        "Active Internet connections (only servers)",
        "Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    ",
        "tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      6088/sshd           ",
        "tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      6400/master         ",
        "tcp6       0      0 :::22                   :::*                    LISTEN      6088/sshd           ",
        "tcp6       0      0 ::1:25                  :::*                    LISTEN      6400/master         ",
        "udp        0      0 0.0.0.0:68              0.0.0.0:*                           5896/dhclient       ",
        "udp        0      0 127.0.0.1:323           0.0.0.0:*                           5552/chronyd        ",
        "udp6       0      0 ::1:323                 :::*                                5552/chronyd        "
    ]
}

PLAY RECAP **********************************************************************************************************************************
192.168.101.15             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

facts变量

facts是ansible中一个非常重要的元素, facts中包含了被采集主机的一些基本信息,包括:被采集端的主机名,CPU,磁盘等一些基本信息。有时候我们需要通过对不同主机设置不同的主机名,此时我们就可以使用facts变量。这些变量是setup模块中的。

如果开启facts会导致采集速度变慢(可以通过 gather_facts: no 关闭facts采集)

- hosts: web
  tasks:
    - name: Installed Memcached
      yum: name=memcached state=present

    - name: Configure Memcached
      template: src=./memcached.j2 dest=/etc/sysconfig/memcached

    - name: Start Memcached
      service: name=memcached state=started enabled=yes
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [Installed Memcached] *****************************************************************************************************
changed: [192.168.101.15]

TASK [Configure Memcached] *****************************************************************************************************
changed: [192.168.101.15]

TASK [Start Memcached] *********************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

条件语句

我们可能会有这样的需求,需要根据不同的操作系统安装相同的软件包。但是不同的系统软件包的名称可能是不一样的,比如apache在ubuntu系统上的软件包名是httpd2, 在centos操作系统上的软件包名称是httpd,因此我们需要的playbook中引入条件判断语句

example.yml

- hosts: web
  tasks:
    - name: Installed httpd Server
      yum: name=httpd state=present
      when: ansible_distribution == "CentOS"

    - name: Installed httpd Server
      apt: name=httpd2 state=present
      when: ansible_distribution == "Ubuntu"
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [Installed httpd Server] **************************************************************************************************
changed: [192.168.101.15]

TASK [Installed httpd Server] **************************************************************************************************
skipping: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

实例: 给 web 开头的主机名添加仓库地址

- hosts: web
  tasks:
    - name: Add Nginx Repository
      yum_repository:
        name: nginx
        description: Nginx Yum Repository
        baseurl: http://nginx.org/packages/centos/7/$basearch/
        gpgcheck: no
      when: (ansible_hostname is match ("web*")) or (ansible_hostname is match ("lb*"))
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [Add Nginx Repository] ****************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

循环语句

有时候我们需要对多台服务器安装多个不一样的服务,比如说mysql, httpd 等, 如果安装之前的方法,我们需要写很多次安装,效率差,因此我们可以使用playbook中的循环语句来进行添加

循环启动多个服务

example.yml

- hosts: all
  tasks:
    - name: start httpd firewalld
      systemd: name={{ item }} state=started
      with_items:
        - httpd
        - firewalld
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [all] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [start httpd firewalld] ***************************************************************************************************
changed: [192.168.101.15] => (item=httpd)
ok: [192.168.101.15] => (item=firewalld)

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

使用定义变量方式循环安装软件包
[root@zhangsan ~]# cat example.yml
- hosts: web
  tasks:
    - name: ensure a list of packages installed
      yum: name={{ packages }} state=present
      vars:
        packages:
          - httpd
          - httpd-tools
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [ensure a list of packages installed] *************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Handlers触发器

当我们安装好一个服务,并且将配置文件推到被控制端的服务器之后,被控端服务并不会重启被控端的服务,因此我们需要一个策略,在我们安装以及配置好服务后,通过这个策略重启服务

[root@zhangsan ~]# cat example.yml
- hosts: web
  vars:
    - http_port: 8060
  tasks:
    - name: install http server
      yum: name=httpd state=present

    - name: configure httpd server
      template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify:
        - Restart Httpd Server
        - Restart PHP Server

    - name: start httpd server
      service: name=httpd state=started enabled=yes

  handlers:
    - name: Restart Httpd Server
      systemd: name=httpd state=restarted

    - name: Restart PHP Server
      systemd: name=php-fpm state=restarted
[root@zhangsan ~]# ansible-playbook example.yml -C -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [install http server] *****************************************************************************************************
ok: [192.168.101.15]

TASK [configure httpd server] **************************************************************************************************
changed: [192.168.101.15]

TASK [start httpd server] ******************************************************************************************************
changed: [192.168.101.15]

RUNNING HANDLER [Restart Httpd Server] *****************************************************************************************
changed: [192.168.101.15]

RUNNING HANDLER [Restart PHP Server] *******************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


Tags

tags主要是用来调试的,因为我们在写playbook的时候,可能会有很多个 task任务,因此我们可以给一些tasks任务打上一些标记,执行的时候,可以根据tag标记来执行对应的任务。

example.yml

- hosts: all
  tasks:
    - name: restart httpd server
      service: name=httpd state=restarted enabled=yes
      tags:
        - restart_httpd

    - name: restart firewalld server
      service: name=firewalld state=restarted enabled=yes
      tags:
        - restart_firewalld
列出所有tag
[root@zhangsan ~]# ansible-playbook example.yml --list-tags -i ./hosts

playbook: example.yml

  play #1 (all): all	TAGS: []
      TASK TAGS: [restart_firewalld, restart_httpd]
运行指定tag
[root@zhangsan ~]# ansible-playbook example.yml -t restart_httpd -i ./hosts

PLAY [all] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [restart httpd server] ****************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

忽略错误

有时候由于上一个Playbook可能执行出错,导致整个程序不能执行下去,如果我们还想继续执行下去的话,可以使用忽略错误这个选项

- hosts: web
  tasks:
    - name: Ignore Error
      command: /bin/false
      ignore_errors: yes

    # 上面如果不忽略错误就会因为报错而退出执行
    - name: touch new file
      file: path=/tmp/test_ignore state=touch
[root@zhangsan ~]# ansible-playbook example.yml -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [Ignore Error] ************************************************************************************************************
fatal: [192.168.101.15]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.006053", "end": "2020-11-03 10:32:41.946471", "msg": "non-zero return code", "rc": 1, "start": "2020-11-03 10:32:41.940418", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [touch new file] **********************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1


Jinja2模板引擎

[root@zhangsan ~]# cat ./database.conf
host=127.0.0.1
port=3306
username=root
password={{ password }}

example.yml

- hosts: web
  tasks:
    - name: copy config file
      template: src=./database.conf dest=/tmp/database.conf
[root@zhangsan ~]# ansible-playbook example.yml --extra-vars 'password=111111' -i ./hosts

PLAY [web] *********************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.101.15]

TASK [copy config file] ********************************************************************************************************
changed: [192.168.101.15]

PLAY RECAP *********************************************************************************************************************
192.168.101.15             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

目标主机

[root@localhost tmp]# cat /tmp/database.conf
host=127.0.0.1
port=3306
username=root
password=111111