Anasible 是基于Python2-Paramiko 模块开发的自动化维护工具,实现了批量系统配置、部署、运行等功能。Ansible是基于模块工作的,本身不具备批量部署的功能,如果想要实现批量自动化部署,是Ansible自身的各种模块的集合。
可以与 Ansible 同台竞技的运维工具( pupet、cfengine、chef、func、fabric、saltstack )
Michael DeHaan
同时他也是 Cobbler 与 Func
作者。Red Hat
收购。ansible-arch
ansible-flow
ansible
主要组成部分:
# Centos
yum -y install ansible
# Ubuntu
apt install -y ansible
# 源码安装
git clone https://github.com/ansible/ansible
# 使用 pip 命令安装
pip install ansible
/etc/ansible/ansible.cfg
主配置文件, 配置ansible
的工作特性.
/etc/ansible/hosts
主机列表清单.
/etc/ansible/roles/
存放(roles)角色的目录.
/usr/local/bin/ansible
二进制执行文件, ansible
主程序.
/usr/local/bin/ansilbe-doc
配置文档, 模块功能查看工具.
/usr/local/bin/ansible-galaxy
用于上传/下载 roles
模块到官方平台的工具.
/usr/local/bin/ansible-playbook
自动化任务、编排剧本工具/usr/bin/ansible-pull
远程执行命令的工具.
/usr/local/bin/ansible-vault
文件(如: playbook 文件) 加密工具.
/usr/local/bin/ansible-console
基于 界面的用户交互执行工具.
创建SSH秘钥 ssh-keygen -t rsa -C "deniss.wang" 拷贝公钥到其他被服务器 ssh-copy-id -i ubuntu@ubuntu20-bj01
hosts
[codo-cluster]
demo.opendevops.cn ansible_ssh_user=root
www.opendevops.cn ansible_ssh_user=root
[k3s-cluster]
ubuntu20-bj01 ansible_user=ubuntu
ubuntu20-bj02 ansible_user=ubuntu
ubuntu20-bj03 ansible_user=ubuntu
ubuntu20-sh04 ansible_user=ubuntu
-m
指定模块执行。如:ping、yum、copy、file等,此处使用模块ping测试。
-k
使用密码方式,默认是使用SSH-KEY登录。
基本示例:
# ansible 通过 单主机进行操作 ( -k 为用户密码方式, 默认为 ssh-key )
ansible 10.0.8.2 -m ping -k
# ansible 通过 ':' 组合进行操作
ansible "10.0.8.2:10.0.8.3" -m ping -k
# ansible 通过 通配符加主机 进行操作
ansible 10.0.8.* -m ping -k
# ansible 通过 hosts 组名称 进行操作
ansible codo -m ping -k
# ansible 通过 ':' 组合组进行操作
ansible 'codo-cluster:k3s-cluster' -m ping -k
# ansible 通过 通配符 进行操作
ansible '*-cluster' -m ping -k
# ansible 通过 ':&' 逻辑与 (两个组中都包含的主机)
ansible 'codo-cluster:&k3s-cluster' -m ping -k
# ansible 通过 ':!' 逻辑非 (codo-cluster 但不在 k3s-cluster的主机)
ansible 'codo-cluster:!k3s-cluster' -m ping -k
# ansible 也支持多逻辑的组合
ansible 'webservers:dbserver:&appserver:!ftpservers' -m ping -k
# ansible 也支持正则表达式
ansible '~(codo|k3s)-cluster' -m ping -k
# ansible 通过 all 对 hosts 清单下所有主机进行操作
ansible all -m ping -k
# ansible 通过 通配符 对 hosts 清单下所有主机进行操作
ansible '*' -m ping -k
执行结果:
# ansible k3s -m 'ping'
ubuntu20-bj03 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
ubuntu20-bj02 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
ubuntu20-bj01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
ubuntu20-sh04 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
# defaults 为默认配置
[defaults]
# 主机清单的路径, 默认为如下
# inventory = /etc/ansible/hosts
# 模块存放的路径
# library = /usr/share/my_modules/
# utils 模块存放路径
# module_utils = /usr/share/my_module_utils/
# 远程主机脚本临时存放目录
# remote_tmp = ~/.ansible/tmp
# 管理节点脚本临时存放目录
# local_tmp = ~/.ansible/tmp
# 插件的配置文件路径
# plugin_filters_cfg = /etc/ansible/plugin_filters.yml
# 执行并发数
# forks = 5
# 异步任务查询间隔 单位秒
# poll_interval = 15
# sudo 指定用户
# sudo_user = root
# 运行 ansible 是否提示输入sudo密码
# ask_sudo_pass = True
# 运行 ansible 是否提示输入密码 同 -k
# ask_pass = True
# 远程传输模式
# transport = smart
# SSH 默认端口
# remote_port = 22
# 模块运行默认语言环境
# module_lang = C
# roles 存放路径
# roles_path = /etc/ansible/roles
# 不检查 /root/.ssh/known_hosts 文件 建议取消
# host_key_checking = False
# ansible 操作日志路径 建议打开
# log_path = /var/log/ansible.log
ansible执行过程
$HOME/.ansible/tmp/ansible-tmp-2123/xxxxxxx.py
>文件.显示帮助信息
使用参数:
-l --list
显示可用模块
-s --snippet
显示指定模块的 playbook
阶段
Demo
# Demo
ansible-doc -l
# ...略过
ansible-doc ping
# 模块ping显示文档
ansible-doc -s ping
ansible <host-pattern> [-m module_name] [-a args]
host-pattern
: 主机ip、主机名、主机组。module_name
: 模块的名称。默认为 -m command
。args
: 模块的参数, 需要加上 -a
进行指定模块的参数。如: `ansible all -a ‘hostname’-v、-vv、-vvv
: 显示详细的命令输出日志, v 越多越详细。如: ansible all -m ping -vvv
--list
: 显示主机的列表。如: ansible all --list
-k / --ask-pass
: 提示输入ssh连接密码, 默认为 ssh-key 认证。如: ansible all -m ping -k
-K / --ask-become-pass
: 提示输入 sudo 的密码。-C / --check
: 检查命令操作, 并不会执行。如: ansible all -m ping -C
-T / --timeout
: 执行命令的超时时间, 默认为 10s。如: ansible all -m ping -T=2
-u / --user
: 执行远程操作的用户. 如: ansible all -m ping -u=root
-b / --become
: 代替旧版的 sudo
切换。截止 2021-10-12 ansible 模块为 6006 个. 不可谓不强大!人生苦短,我用Python!
在远程主机上执行命令, 支持条件判断. ansible 默认模块, 可忽略 -m
参数直接操作.
注意: command
模块 不支持 $VARNAME
<
>
|
;
&
等符号.
Demo
# 停止docker服务
ansible k3s-cluster -m command -a 'systemctl stop docker'
# 查看所有docker镜像
ansible k3s-cluster -a 'docker ps -a'
# 如果 /opt/ansible 不存在 就不执行 df -h 操作, 如果 /opt/ansible 存在, 就执行 df -h 操作.
ansible k3s-cluster -a 'removes=/mnt/ansible df -h'
# 如果 /opt/ansible 不存在 就执行 df -h 操作, 如果存在 /opt/ansible 就不执行 df -h 操作.
ansible k3s-cluster -a 'creates=/mnt/ansible df -h'
# 切换目录, 等同于 cd /mtn && ls -lt 操作
ansible k3s-cluster -a 'chdir=/mnt ls -lt'
shell
模块: shell 模块支持 command 所有的操作, 而且支持 $VARNAME
<
>
|
;
&
等符号操作.
Demo:
# 查看docker进程
ansible k3s-cluster -m shell -a 'ps -ef|grep docker'
script
模块: 执行脚本. 只需要调用 ansible 的宿主机存放的脚本文件就可以在选择主机上面执行脚本.
Demo
# shell
cat /tmp/deniss.sh
#!/bin/bash
echo "测试 shell"
ansible k3s-cluster -m script -a '/tmp/deniss.sh'
# python
cat /tmp/deniss.py
#!/usr/bin/python
import sys
print ('Deniss_Wang' )
print (sys.version)
ansible k3s-cluster -m script -a '/tmp/deniss.py'
# 其他脚本也是可以的,只需要配置好环境语言解释即可。
copy
模块: 复制ansible宿主机文件到目标主机.
Demo
# src="" 宿主机路径 dest="" 目标主机路径 backup=yes 如果目标主机文件存在, 会备份, 再覆盖.
ansible k3s-cluster -m copy -a ‘src=/tmp/deniss.py dest=/tmp/deniss.py backup=yes
# mode="" 修改权限, owner="" 修改用户, group="" 修改用户组
ansible k3s-cluster -m copy -a 'src=/root/deniss.py dest=/root/deniss.py mode=0644 owner=deniss group=deniss'
# content="" 将内容写入到目标文件中
ansible k3s-cluster -m copy -a 'content="hello\nworld\n" dest=/tmp/deniss.txt'
fetch
模块: 将目标远程主机的文件, 下载到本地, 下载成功会存放在以 IP/NAME的目录中, 包含原文件的整体路径.
注意:只能下载单个文件, 不支持目录, 想下载完整路径,可以压缩后在下载。
Demo
# src="" 目标远程主机的文件路径 dest="" 本地目录
ansible k3s-cluster -m fetch -a 'src=/var/log/syslog dest=/tmp/'
file
模块: 操作远程目标主机的文件. 如: touch
、 absent
等.
Demo
# mode="" 修改权限 owner="" 修改用户 group="" 修改用户组 recurse=yes 递归授权
ansible k3s-cluster -m file -a 'name=/tmp/deniss.txt owner=ubuntu group=ubuntu mode=0755 recurse=yes'
# dest、name、path: 指定远程主机的文件路径,state: 文件操作类型,默认为 absent,touch: 创建空文件.
ansible k3s-cluster -m file -a 'name=/tmp/deniss.txt state=touch'
# directory: 创建文件夹, absent: 递归删除文件夹/文件,link: 创建软连接.
ansible k3s-cluster -m file -a 'src=/tmp/deniss.txt dest=/tmp/deniss.link state=link'
cron
模块: 为远程主机添加定时任务
day
: 表示 天. 支持 ( 1-31, *, */2 ) 写法hour
: 表示 小时. 支持 ( 0-23, *, */2 ) 写法minute
: 表示 分钟. 支持 ( 0-59, *, */2 ) 写法month
: 表示 月. 支持 ( 1-12, *, */2 ) 写法weekday
: 表示 星期. 支持 ( 0-6, Sunday-Saturday, * )写法job
: 表示 计划任务的内容.name
: 表示 计划任务名称. 相同的计划任务名称会覆盖.Demo
# day: 表示 天. 支持 ( 1-31, *, */2 ) 写法
# hour: 表示 小时. 支持 ( 0-23, *, */2 ) 写法
# minute: 表示 分钟. 支持 ( 0-59, *, */2 ) 写法
# month: 表示 月. 支持 ( 1-12, *, */2 ) 写法
# weekday: 表示 星期. 支持 ( 0-6, Sunday-Saturday, * )写法
# job: 表示 计划任务的内容.
# name: 表示 计划任务名称. 相同的计划任务名称会覆盖.
ansible k3s-cluster -m cron -a 'weekday=1-5 job="echodate>> /tmp/1.txt" name=echocron'
# disabled= (true/false、yes/no)注释掉计划任务 关闭、启动计划任务 必须指定job和name.
ansible k3s-cluster -m cron -a 'disabled=true job="echodate>> /root/1.txt" name=echocron'
# state=absent 删除计划任务。
ansible k3s-cluster -m cron -a 'name=echocron state=absent'
yum
模块: 利用 yum 操作软件包, 如 安装、查询、卸载等.
Demo
# name: 软件包的名称, 或者rpm包, 远程服务器必须存在 rpm 包. 安装多个软件使用 ,号隔开. 如 name=nginx,php,mysql
# state="present/installed/absent/removed"
# present、installed: 安装软件.
# absent、removed: 卸载/删除软件.
# update_cache=yes: 更新 yum 缓存后 在安装软件 disable_gpg_check=yes: 禁用 gpg 检查.
ansible k3s-cluster -m yum -a 'name=mysql state=present'
ansible k3s-cluster -m yum -a 'name=/tmp/nginx-xx.x.x-x.x.x86_64.rpm'
ansible k3s-cluster -m yum -a 'name=nginx update_cache=yes disable_gpg_check=yes'
# list="updates/installed/available/repos" 指定获取状态
# 状态释义: installed: 已安装的软件 updates: 可以升级的软件 available: 可以安装的软件 repos: yum 源
ansible k3s-cluster -m yum -a 'list=installed'
service
: 软件服务管理模块. 启动、关闭、重启 等操作.
# name="",安装名字
# state="started/stopped/restarted/reloaded" 启动、停止、重启、重载
# enable="yes/no、true/false" 设置是否开机自启
ansible k3s-cluster -m service -a 'name=nginx state=started enabled=yes'
user
: 管理系统用户的模块
Demo
# name"" 用户名
# shell="" 指定用户的shell类型
# system="yes/no" 指定是否为 系统用户
# home="" 指定用户额外的home目录, 默认/home/user .
# groups="" 用户额外的 groups 组.
# uid="" 指定用户的UID.
# comment="" 用户描述
ansible k3s-cluster -m user -a 'name=deniss shell=/sbin/nologin system=yes home=/tmp/deniss groups=root uid=777 comment="deniss user"'
# state="present/absent"
# present: 创建用户 (默认为present) absent: 删除用户
ansible k3s-cluster -m user -a 'name=deniss state=absent remove=yes'
ansible k3s-cluster -m user -a 'name=nginx state=absent remove=yes'
group
: 管理系统用户组的模块.
Demo
# name"" 用户名
# system="yes/no" 指定是否为 系统用户
# home="" 指定用户额外的home目录, 默认/home/user .
# gid="" 指定GID.
# state="present/absent"
# present: 创建用户组 (默认为present) absent: 删除用户组
# 创建
ansible all -m group -a 'name=deniss system=yes gid=777'
# 删除
ansible all -m group -a 'name=deniss state=absent'
官网 https://galaxy.ansible.com/
ansible-galaxy 工具用于下载对应的roles
# list 查看本地的 roles 角色。
ansible-galaxy list geerlingguy.nginx
# install 下载 roles 角色存放到$HOME/.ansible/roles/目录下。
ansible-galaxy install geerlingguy.nginx
# remove 删除已下载的 roles 角色,也可以在存放目录中删除。
ansible-galaxy remove geerlingguy.nginx
playbook
由一个或多个 play
组成.playbook
中 每个play
必须包含 hosts
和 tasks
.playbook
以 yaml
语法编写.YAML
约定以 ---
开头 和 开始不同的 play
.YAML
以 #
作为注释.YAML
必须统一缩进, 空格 与 tab
不能混用, 缩进的级别也必须相同, 同级缩进代表同样的级别.YAML
文件内容 是大小写敏感的, 跟 Linux 一样区分大小写.YAML
key/value 形式可写在同一行也可以换行写. 同行使用 :
隔开.YAML
一个完整的代码块功能最少包含2个元素. 如 name: taskYAML
一个 name 下只能包含一个 taskYAML
-
开头的为列表, key/value
形式的为字典.YAML
特性hosts
远程主机列表 ( ip_addr/hostname/groupname )tasks
任务集, 任务列表, 有两种写法。action: module args
action 参数。module: args
参数 (一般使用这种)。ignore_errors: True
当前 task 出错时仍然会向下执行。varniables
内置变量或自定义变量在 playbook
文件中调用。templates
模板,可替换模板文件中的变量并实现一些简单逻辑的文件。handles
与 notity
结合使用, 由特定条件触发的操作, 满足条件执行, 否则不执行。tags
标签 指定任务执行, 用于执行一个 playbook
中的部分代码. 主要用于测试ansible的语法与执行验证。ansible-playbook
-C --check
Check 检查脚本运行情况, 不会在远程服务器里运行。--list-hosts
列出执行此任务的主机。--list-tasks
列出任务组的具体任务列表。--limit
只对主机列表中的某台主机执行。-v -vv -vvv
显示详细的执行DEBUG信息过程, 多个v
参数等于DEBUG信息的叠加,显示更为详细。fact
,在此只对 fact
做详细讲解,其他的就不过多叙述了,如果想了解详细信息,可以访问官方文档获取帮助。# ansible k3s-cluster -m setup
ubuntu20-bj03 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.16.4"
],
"ansible_all_ipv6_addresses": [
"fe80::5054:ff:fed6:42a8"
],
"ansible_apparmor": {
"status": "enabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "04/01/2014",
"ansible_bios_vendor": "SeaBIOS",
"ansible_bios_version": "seabios-1.9.1-qemu-project.org",
"ansible_board_asset_tag": "NA",
"ansible_board_name": "NA",
"ansible_board_serial": "NA",
"ansible_board_vendor": "NA",
"ansible_board_version": "NA",
"ansible_chassis_asset_tag": "NA",
"ansible_chassis_serial": "NA",
"ansible_chassis_vendor": "Smdbmds",
"ansible_chassis_version": "3.0",
# 多余的冗余信息就不放了,自己可以执行验证下。
# setup获得变量信息,都可以用于继承给playbook调用。
}
fact
。
本地 fact
默认存放宿主机的/etc/ansible/facts.d
目录下,支持的文件格式为ini、json。
加载后的fact的key是ansible_local的特殊变量。
denis_test.fact
[general]
package = vsftpd
service = vsftpd
state = starte
setup_facts.yaml
---
- name: Install Remote Facts
hosts: k3s-cluster
vars:
remote_dir: /etc/ansible/facts.d
facts_file: denis_test.fact
tasks:
- name: Create Directory
file:
state: directory
recurse: yes
path: "{{ remote_dir }}"
- name: Install the new facts
copy:
src: "{{ facts_file }}"
dest: "{{ remote_dir }}"
执行测试
# ansible-playbook setup_facts.yaml
# ansible test -m setup
ubuntu20-bj03 | SUCCESS => {
"ansible_facts": {
# -----分隔符-----
"ansible_local": {
"custom": {
"general": {
"package": "vsftpd",
"service": "vsftpd",
"state": "started"
}
}
},
# -----分隔符-----
}
调用测试
deniss_test.yaml
- name: Install Apache and starts the service
hosts: k3s-cluster
tasks:
- name: Install Package
yum:
name: "{{ ansible_facts.ansible_local.custom.general.package }}"
state: latest
- name: Start Service
service:
name: "{{ ansible_facts.ansible_local.custom.general.service }}"
state: "{{ ansible_facts.ansible_local.custom.general.state }}"
deniss_fact_demo.yaml
- name: set_fact demo
hosts: k3s-cluster
tasks:
- name: Calculate InnoDB buffer pool size
set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 |int }}"
- debug: var=innodb_buffer_pool_size_mb
执行测试
# ansible-playbook deniss_fact_demo.yaml
PLAY [set_fact demo] *****************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [Calculate InnoDB buffer pool size] ************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [debug] ****************************************************************************************************************************************************************
ok: [ubuntu20-bj03] => {
"innodb_buffer_pool_size_mb": "2911.2"
}
PLAY RECAP ******************************************************************************************************************************************************************
ubuntu20-bj03 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- hosts: k3s-cluster
name: test demo
gather_facts: False
tasks:
- name: wait for ssh to be running
local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
- name: gather facts
setup:
gather_facts: False
;gather_facts: Ture
。[defaults]
gathering = smart
# 缓存时间
fact_caching_timeout = 86400
fact_caching = {jsonfile/redis/memcached}
# 指定ansible包含fact的json文件位置,如果目录不存在,会自动创建
# local
fact_caching_connection = /tmp/ansible_fact_cache
# redis
fact_caching_connection = 127.0.0.1:6379:admin
# memcached
fact_caching_connection = ['127.0.0.1:11211']
# playbook 配置
- hosts: k3s-cluster
gather_facts: no
# ansible.cfg 配置
[defaults]
gathering = explicit
字母
、数字
、 _
组成, 而且只能以 字母
开头。ansible k3s-cluster -m setup -a 'filter=*addresses*'
可使用 filter 参数进行过滤ansible k3s-cluster -m setup
可以获取到主机的系统变量名称/etc/ansible/hosts
文件中定义[appserver]
# 定义变量 node_id
10.0.8.2 node_id=17
# 对主机组 定义统一变量 domain_name
[k3s-cluster:vars]
domain_name=deniss.wang
hostname
---
- hosts: k3s-cluster
become: yes
become_user: root
tasks:
- name: set hostname
hostname: name={{ node_id }}.{{ domain_name }}
---
- hosts: k3s-cluster
remote_user: root
# 定义变量
vars:
- pkg_name: httpd
- env_name: prod
tasks:
- name: {{ env_name }} install {{ pkg_name }}
yum: name={{ pkg_name }}
key: value
形式写入到 yaml
文件中既可。playbook
文件中, 只需要使用 vars_files:
指定 yaml
文件路径既可。---
pkg_name: httpd
file_name: deniss.wang
---
- hosts: k3s-cluster
remote_user: root
# 配置模板文件
vars_files:
# 指定文件的路径
- vars.yaml
tasks:
- name: install {{ pkg_name }}
yum: name={{ pkg_name }}
- name: create {{ file_name }} file
file: name=/tmp/{{ file_name }}.txt state=touch
# ansible-playbook install.yaml
PLAY [k3s-cluster] *******************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************
ok: [10.0.8.2]
TASK [install httpd] *********************************************************************************************
changed: [10.0.8.2]
TASK [create deniss.wang file] **************************************************************************************
changed: [10.0.8.2]
PLAY RECAP *******************************************************************************************************
10.0.8.2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
xx.j2
,只能用于 playbook。templates
文件, 可嵌套引用脚本。+
, -
, *
, /
, //
, %
, **
==
, !=
, >
, >=
, <
, <=
Jinja2
语法:templates
根据模板块文件动态生成对应的配置文件templates
的模板文件必须存放于 templates 目录下, 并且以 .j2
为后缀。playbook
的 yaml
文件在同级目录中。# tree nginx/
|-- nginx.yaml
|-- templates
|-- nginx.conf.j2
“算术运算
user nginx;
# 这里使用 环境变量 vcpus * 2,会根据操作系统CPU自动生成。
worker_processes {{ ansible_processor_vcpus * 2 }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 10240;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
---
- hosts: k3s-cluster
become: yes
become_user: root
tasks:
- name: install nginx
yum: name=nginx
- name: nginx template conf
# 如果yaml与templates在同一目录, src直接写.j2文件
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify:
- restart nginx
- name: start nginx
service: name=nginx state=started enabled=yes
handlers:
- name: restart nginx
service: name=nginx state=restarted
“when 条件语句
when
条件语句 例子# tree nginx
|-- nginx.yaml
|-- templates
|-- nginx.conf.centos7.j2
|-- nginx.conf.centos8.j2
playbook
文件---
- hosts: k3s-cluster
become: yes
become_user: root
tasks:
- name: install nginx
yum: name=nginx
- name: template centos 7 conf
# 如果 yaml 与 templates 在同一目录, src 直接写.j2 文件。
template: src=nginx.conf.centos7.j2 dest=/etc/nginx/nginx.conf
# 使用 when 语句进行判断 如果变量为 "7" 执行以下操作
when: ansible_distribution_major_version == "7"
notify:
- restart nginx
- name: template centos 8 conf
# 同上
template: src=nginx.conf.centos8.j2 dest=/etc/nginx/nginx.conf
# 使用 when 语句进行判断 如果变量为 'Ubuntu' 且版本为20 执行以下操作
when: (ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "20"
notify:
- restart nginx
- name: start nginx
service: name=nginx state=started enabled=yes
handlers:
- name: restart nginx
service: name=nginx state=restarted
skipping
状态表示跳过执行这个 TASK。# ansible-playbook nginx.yml
PLAY [k3s-cluster] *******************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.8.2]
TASK [install nginx] *********************************************************************************
ok: [10.0.8.2]
TASK [template centos 7 conf] ************************************************************************
changed: [10.0.8.2]
TASK [template centos 8 conf] ************************************************************************
skipping: [10.0.8.2]
TASK [start nginx] ***********************************************************************************
ok: [10.0.8.2]
RUNNING HANDLER [restart nginx] **********************************************************************
changed: [10.0.3.13]
PLAY RECAP *******************************************************************************************
10.0.8.2 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
“迭代变量
with_tiems
with_items
执行重复任务。item
。task
中使用 with_items
指定需要迭代的元素列表。字符串
和 字典
。---
- hosts: k3s-cluster
become: yes
become_user: root
tasks:
- name: create multi files
# {{ item }} 为内置特殊变量, 代表 with_items 列表中的内容
file: name=/tmp/{{ item }} state=touch
with_items:
- file_one
- file_two
- file_three
- file_four
- name: install multi software
yum: name={{ item }}
with_items:
- vsftpd
- net-tools
- iftop
“代嵌套子变量 (字典)
playbook
文件---
- hosts: k3s-cluster
become: yes
become_user: root
tasks:
- name: create some files
# {{ item }} 为特殊变量, 代表 with_itmes 列表中的内容
file: name=/tmp/{{ item }} state=touch
with_items:
- file_one
- file_two
- file_three
- file_four
- name: create multi group
group: name={{ item }}
with_items:
- jinja2_file1
- jinja2_file2
- jinja2_file3
- jinja2_file4
- name: create multi user
# 使用 item.key值 进行引用
user: name={{ item.name }} group={{ item.group }}
# 使用 字典 定义 嵌套的子 变量
with_items:
- { name: 'file_one', group: 'jinja2_file1' }
- { name: 'file_two', group: 'jinja2_file2' }
- { name: 'file_three', group: 'jinja2_file3' }
- { name: 'file_four', group: 'jinja2_file4' }
- name: permission multi files
file: name=/tmp/{{ item.name }} owner={{ item.name }} group={{ item.group }}
with_items:
- { file: 'file_one', name: 'file_one', group: 'jinja2_file1' }
- { file: 'file_two', name: 'file_two', group: 'jinja2_file2' }
- { file: 'file_three', name: 'file_three', group: 'jinja2_file3' }
- { file: 'file_four', name: 'file_four', group: 'jinja2_file4' }
playbook
文件# ansible-playbook file.yml
PLAY [k3s-cluster] *****************************************************************************************
TASK [Gathering Facts] *****************************************************************************
ok: [10.0.8.2]
TASK [create multi files] ***************************************************************************
changed: [10.0.8.2] => (item=file_one)
changed: [10.0.8.2] => (item=file_two)
changed: [10.0.8.2] => (item=file_three)
changed: [10.0.8.2] => (item=file_four)
TASK [create multi group] ***************************************************************************
changed: [10.0.8.2] => (item=jinja2_file1)
changed: [10.0.8.2] => (item=jinja2_file2)
changed: [10.0.8.2] => (item=jinja2_file3)
changed: [10.0.8.2] => (item=jinja2_file4)
TASK [create multi user] ****************************************************************************
changed: [10.0.8.2] => (item={u'group': u'jinja2_file1', u'name': u'file_one'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file2', u'name': u'file_two'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file3', u'name': u'file_three'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file4', u'name': u'file_four'})
TASK [permission multi files] ***********************************************************************
changed: [10.0.8.2] => (item={u'group': u'jinja2_file1', u'name': u'file_one', u'file': u'file1'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file2', u'name': u'file_two', u'file': u'file2'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file3', u'name': u'file_three', u'file': u'file3'})
changed: [10.0.8.2] => (item={u'group': u'jinja2_file4', u'name': u'file_four', u'file': u'file4'})
PLAY RECAP *****************************************************************************************
10.0.8.2 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
“ 流程控制、循环 for 与 if
{% for 语句块 %} ... {% endfor %}
---
- hosts: k3s-cluster
become: yes
become_user: root
vars:
# 列表
listen_port:
- 80
- 81
- 82
# 字典
service:
- name: web1
domain: deniss.wang
port: 9090
user: nginx
path: /var/www/html
- name: web2
domain: deniss.wang
port: 9091
user: nginx
path: /var/www/html
- name: web3
domain: deniss.wang
port: 9092
user: nginx
path: /var/www/html
tasks:
- name: copy template conf
template: src=for.conf.j2 dest=/tmp/for.conf
{% for port in listen_port %}
语句 listen_port
为 playbook 中定义的 vars
。{% for port in listen_port %}
server {
listen {{ port }}
}
{% endfor %}
# cat /root/for.conf
server {
listen 80
}
server {
listen 81
}
server {
listen 82
}
---
- hosts: k3s-cluster
become: yes
become_user: root
vars:
# 字典的形式
service:
- name: web1
domain: deniss.wang
port: 9090
user: nginx
path: /var/www/html
- name: web2
domain: deniss.wang
port: 9091
user: nginx
path: /var/www/html
- name: web3
domain: deniss.wang
port: 9092
user: nginx
path: /var/www/html
tasks:
- name: copy template conf
template: src=nginx.conf.j2 dest=/tmp/nginx.conf
{% for s in service %}
user {{ s.user }};
worker_processes {{ ansible_processor_vcpus * 2 }};
pid /run/nginx.pid;
server {
listen {{ s.port }} default_server;
listen [::]:{{ s.port }} default_server;
server_name {{ s.name }}.{{ s.domain }};
root {{ s.path }};
}
{% endfor %}
{% if 语句块 %} ... {% else %} ... {% endif %}
---
- hosts: k3s-cluster
become: yes
become_user: root
vars:
# 字典
service:
- name: web1
domain: deniss.wang
port: 90
path: /var/www/html
- name: web2
domain: deniss.wang
port: 91
path: /var/www/html
- name: web3
domain: deniss.wang
port: 92
user: nginx
path: /var/www/html
tasks:
- name: copy template conf
template: src=nginx2.conf.j2 dest=/tmp/nginx2.conf
{% if s.user is defined %}
判断 是否有 s.user 这个变量{% for s in service %}
{% if s.user is defined %}
user {{ s.user }};
{% else %}
user root;
{% endif %}
worker_processes {{ ansible_processor_vcpus * 2 }};
pid /run/nginx.pid;
server {
listen {{ s.port }} default_server;
server_name {{ s.name }}.{{ s.domain }};
root {{ s.path }};
}
{% endfor %}
user root;
user root;
user nginx;
等于变量值# cat nginx2.conf
user root;
worker_processes 4;
pid /run/nginx.pid;
server {
listen 90 default_server;
server_name web1.deniss.wang;
root /var/www/html;
}
user root;
worker_processes 4;
pid /run/nginx.pid;
server {
listen 91 default_server;
server_name web2.deniss.wang;
root /var/www/html;
}
user nginx;
worker_processes 4;
pid /run/nginx.pid;
server {
listen 92 default_server;
server_name web3.deniss.wang;
root /var/www/html;
}
Demo
---
# 指定主机组
- hosts: k3s-cluster
# 开启提权,指定用户
become: yes
become_user: root
# 任务
tasks:
# 任务的名称
- name: ping server
ping:
- name: echo hostname
# shell 为模块名, 后面等同于 -a '' 参数
shell: hostname
- name: touch file
file: name=/tmp/file.txt state=touch
- name: echo file
shell: ls -l /tmp/file.txt
- name: write file
shell: echo "hello world" > /tmp/file.txt
- name: copy module write file
copy: content="hello deniss\n" dest=/tmp/deniss.txt
- name: display file content
shell: cat /tmp/file.txt
register: display_content1
- name: show
debug: var=display_content1.stdout verbosity=0
- name: display copy module file content
shell: cat /tmp/deniss.txt
register: display_content2
- name: show
debug: var=display_content2.stdout verbosity=0
# ansible-playbook hello.yaml
PLAY [k3s-cluster] *******************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [ping server] *******************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [echo hostname] *****************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [touch file] ********************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [echo file] *********************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [write file] ********************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [copy module write file] ********************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [display file content] **********************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [show] **************************************************************************************************************************************************************************
ok: [ubuntu20-bj03] => {
"display_content1.stdout": "hello world"
}
TASK [display copy module file content] **********************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [show] **************************************************************************************************************************************************************************
ok: [ubuntu20-bj03] => {
"display_content2.stdout": "hello deniss"
}
PLAY RECAP ***************************************************************************************************************************************************************************
ubuntu20-bj03 : ok=11 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ok
: ok 未修改文件元数据,绿色changed
: 数据有修改,黄色handles
与 notity
结合的例子name
下可以定义多个 notify
配置关联到不同的 handlers
中。---
# 指定主机组
- hosts: k3s-cluster
# 开启提权,指定用户
become: yes
become_user: root
tasks:
- name: copy httpd.conf
copy: src=~/ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf backup=yes
# 关联多个触发器的写法
notify:
- restart httpd
- check status httpd
- check network port
Demo
Centos
---
# 指定主机组
- hosts: k3s-cluster
# 开启提权,指定用户
become: yes
become_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: copy httpd.conf
copy: src=/opt/ansible/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf backup=yes
# 此任务 如果有变动会触发如下定义名称的触发器
notify: restart httpd
- name: start httpd
service: name=httpd state=started enabled=yes
# 触发器, 需要配置 notify 触发
handlers:
- name: restart httpd
service: name=httpd state=restarted
Ubuntu
---
# 指定主机组
- hosts: k3s-cluster
# 开启提权,指定用户
become: yes
become_user: root
tasks:
- name: Update apt-get repo and cache
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Install Vsftpd
apt:
name: vsftpd
- name: copy vsftpd.conf
copy: src=/opt/ansible/conf/vsftpd.conf dest=/etc/vsftpd.conf backup=yes
notify: restart vsftpd
- name: start vsftpd
service: name=vsftpd state=started enabled=yes
# 配置 notify 触发,修改配置文件的时候生效。
handlers:
- name: restart vsftpd
service: name=vsftpd state=restarted
# ansible-playbook install_vsftpd.yaml
PLAY [k3s-cluster] *******************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [Update apt-get repo and cache] *************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [Install Vsftpd] ****************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [copy vsftpd.conf] **************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [start vsftpd] ******************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
PLAY RECAP ***************************************************************************************************************************************************************************
ubuntu20-bj03 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ansible-playbook install_pkg.yaml
PLAY [k3s-cluster] *******************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [Update apt-get repo and cache] *************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [Install Vsftpd] ****************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [copy vsftpd.conf] **************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
TASK [start vsftpd] ******************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
RUNNING HANDLER [restart vsftpd] *****************************************************************************************************************************************************
changed: [ubuntu20-bj03]
PLAY RECAP ***************************************************************************************************************************************************************************
ubuntu20-bj03 : ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tags
tags
后可通过定义的 tags
单独运行该 tags
来执行指定的tasks, 运行多个可用 ,
号分隔。tags
。---
# 指定主机组
- hosts: k3s-cluster
# 开启提权,指定用户
become: yes
become_user: root
tasks:
- name: Update apt-get repo and cache
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Install Vsftpd
apt:
name: vsftpd
- name: copy vsftpd.conf
copy: src=conf/vsftpd.conf dest=/etc/vsftpd.conf backup=yes
notify: restart vsftpd
# 定义标签
tags: cpconf
- name: start vsftpd
service: name=vsftpd state=started enabled=yes
# 定义标签
tags: upvsftpd
# 配置 notify 触发,修改配置文件的时候生效。
handlers:
- name: restart vsftpd
service: name=vsftpd state=restarted
-t
指定标签执行# ansible-playbook -t upvsftpd install_vsftpd.yaml
PLAY [k3s-cluster] *******************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [start vsftpd] ******************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
PLAY RECAP ***************************************************************************************************************************************************************************
ubuntu20-bj03 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ansible-playbook -t cpconf install_vsftpd.yaml
PLAY [k3s-cluster] *******************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [ubuntu20-bj03]
TASK [copy vsftpd.conf] **************************************************************************************************************************************************************
changed: [ubuntu20-bj03]
RUNNING HANDLER [restart vsftpd] *****************************************************************************************************************************************************
changed: [ubuntu20-bj03]
PLAY RECAP ***************************************************************************************************************************************************************************
ubuntu20-bj03 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
playbook
文件加密工具。ansible-vault encrypt hello.yaml
encrypt
: AES256 加密 ( 会提示输入密码 )。view
: 加密的情况下 查看 原来的内容。edit
: 编辑加密的 playbook 文件。decrypt
: 解密。rekey
: 修改加密密码。ansible-console
: 可交互执行命令, 支持 Tab
键。# ansible-consoleWelcome to the ansible console.Type help or ? to list commands.deniss.wang@all (10)[f:5]$
root@all (10) [f:5]$
root
当前执行用户。all
表示当前主机列表。(10)
表示当前主机清单下包含 10
台主机。[f:5]
: 表示并发执行任务数为 5
个。。Roles
角色是 Ansible v1.2 版本新加入特性,用于层次性、结构化的组织 playbook
。Roles
能够根据层次结构自动加载- 变量文件、tasks、handler、template 文件等. 简单来讲就是将 这些文件归类到各自单独的文件目录中, 使 playbook 文件可以更好的通过 include
这些文件目录。Roles
一般用于基于 主机构建服务
的场景中, 但也可以用于构建 守护进程
等场景。Roles
默认的目录为 /etc/ansible/roles
。playbook.yml
- 剧本文件app
具体的角色项目名称, 比如 Nginx、PHP、Apachefiles
用于存放由copy
或script
模块调用的文件templates
用于存放 Jinja2
模板, template
模块会自动在此目录中寻找 Jinja2
模板文件tasks
main.yml
文件为入口, 用于定义此角色的任务列表, 此文件可以使用include
包含其它的位于此目录的 task
文件handlers
main.yml
文件为入口, 用于定义此角色中触发条件时执行的动作vars
main.yml
文件为入口,用于定义此角色用到的变量defaults
main.yml
文件为入口, 用于为当前角色设定默认变量meta
main.yml
文件为入口,用于定义此角色的特殊设定及其依赖关系roles
: 所有的角色必须放在roles目录下, 这个目录可以自定义位置,默认的位置在 /etc/ansible/roles
# tree .
|-- nginx
|-- defaults
|-- files
|-- handlers
|-- meta
|-- tasks
|-- templates
|-- vars
# tree roles/
roles/
|-- nginx
|-- defaults
|-- files
|-- handlers
|-- meta
|-- tasks
| |-- group.yaml
| |-- main.yaml
| |-- restart.yaml
| |-- start.yaml
| |-- template.yaml
| |-- user.yaml
| |-- yum.yaml
|-- templates
| |-- nginx.conf.j2
|-- vars
/etc/ansible/nginx_roles.yml
与 roles存放位置在同一目录。---
- hosts: k3s-cluster
become: yes
become_user: root
# 选择 调用的 roles 属性
roles:
# 调用定义好的role,存放在roles目录中。
- role: nginx
/etc/ansible/roles/nginx/tasks/main.yml
入口文件 配置 task 执行顺序。- include: roles/httpd/tasks/copyfile.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml
/etc/ansible/roles/nginx/tasks/group.yml
单独的 tasks 文件只写单独的内容 如下:- name: create group
group: name=nginx gid=80
nginx_roles.yml
文件# ansible-playbook nginx_roles.yml
PLAY [k3s-cluster] ****************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [10.0.8.2]
TASK [nginx : create group] ***********************************************************************
changed: [10.0.8.2]
TASK [nginx : create user] ************************************************************************
changed: [10.0.8.2]
TASK [nginx : install package] ********************************************************************
changed: [10.0.8.2]
TASK [nginx : copy conf] **************************************************************************
changed: [10.0.8.2]
TASK [nginx : start service] **********************************************************************
changed: [10.0.8.2]
PLAY RECAP ****************************************************************************************
10.0.8.2 : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
“roles tags 标签
- hosts: k3s-cluster
become: yes
become_user: root
# 选择 roles 属性
roles:
# 配置相应的 tags 用 { } 引用
- { role: nginx, tags: ['web', 'nginx'] }
- { role: mysql, tags: ['db', 'mysql'] }
- { role: redis, tags: ['db', 'redis'] }
- { role: golang, tags: ['web', 'golang'] }
- { role: vue, tags: ['web', 'vue'] }
- { role: app_demo, tags: "app_demo" }
ansible-playbook -t
参数指定 tags 进行单独调用# ansible-playbook -t web playbook.yml
“roles when 语句
ansible_distribution_major_version == "7"
---
- hosts: all
become: yes
become_user: root
# 选择 roles 属性
roles:
# 配置相应的 tags 用 { } 引用
- { role: nginx, tags: ['web', 'nginx'] }
- { role: mysql, tags: ['db', 'mysql'] }
- { role: redis, tags: ['db', 'redis'] }
# 只针对操作系统为 Centos7 的执行
- { role: golang, tags: ['web', 'golang'], when: ansible_distribution_major_version == "7" }
# 只针对操作系统为 Ubuntu20 的执行
- { role: vue, tags: ['web', 'vue'], when: (ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "20")}
- { role: app, tags: "app" }
--extra-vars
执行 playboook 的时候以参数方式传入变量。# 以变量方式传参
ansible-playbook deploy.yaml --extra-vars "hosts=k3s-cluster user=ubuntu"
# 以json格式传参
ansible-playbook deploy.yaml --extra-vars "{'app_name':'nginx', 'pkg_name':'vsftpd'}"
# 以json文件方式传参
ansible-playbook deploy.yml --extra-vars "@test_vars.json"
Demo
Ubuntu 安装软件,传入参数即可安装软件。
---
# 定义集群,并设置提权root,
- hosts: all
become: yes
become_user: root
vars:
# 传入参数
- DEPLOY_USER: ubuntu
- APP_NAME: '{{ app_name }}'
tasks:
- name: 更新 apt-get 仓库以及缓存
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: 安装 {{ APP_NAME }} 程序
apt:
name: "{{ APP_NAME }}"
# - name: "复制 {{ APP_NAME }} 配置文件"
# copy: src=./conf/vsftpd.conf dest=/etc/{{ APP_NAME }}.conf backup=yes
# notify: restart {{ APP_NAME }} # 此处必须与handlers一致
# # 定义标签
# tags: copyconf
- name: "启动 {{ APP_NAME }} 服务"
service: name={{ APP_NAME }} state=started enabled=yes
# 定义标签
tags: startvsftpd
# 配置 notify 触发,修改配置文件的时候生效。
handlers:
- name: restart {{ APP_NAME }}
service: name={{ APP_NAME }} state=restarted
发布流程,Demo中的具体实现逻辑,需要根据自己的环境来定义,此处仅做参考
---
- hosts: all
gather_facts: no
vars:
# OSS参数
- OSS_URL: 'https://repo.opendevops.cn'
- OSS_PATH: 'codo/codo-api/cclib/production'
- OSS_FILE: 'xxxxx_20211020181130_dispatch-service-0.0.7.jar'
- OSS_FILE_KEY: '?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# 部署参数
- DEPLOY_USER: '{{ deploy_user }}' # "ubuntu"
- APP_NAME: '{{ app_name }}' # "tomcat"
- APP_DIR: '{{ app_dir }}' # "/tmp"
- DING_URL: '{{ ding_url }}'
- DING_TOKEN: '{{ ding_token }}'
tasks:
- name: "验证 {{ inventory_hostname }} SSH 端口"
local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
- name: gather facts
setup:
- name: "钉钉 {{ ding_url }} {{ ding_token }}"
shell: "echo {{ ding_url }}"
register: print_ding_url
- name: "获取当前发布主机IP"
shell: "curl http://ip.me"
register: get_ip_addr
- name: "获取当前发布主机IP SDTOUT"
debug: var=get_ip_addr.stdout
- name: "获取当前发布主机名称"
shell: "hostname"
register: get_hostname
- name: "获取当前发布主机名称 SDTOUT"
debug: var=get_hostname
# 发布的一些动作
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 目录"
file:
path: "{{ APP_DIR }}/{{ APP_NAME }}"
state: directory
mode: '0755'
register: create_dir
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 目录 STDOUT"
debug: var=create_dir
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 程序包下载"
shell: "wget {{ OSS_URL }}/{{ OSS_PATH }}/{{ OSS_FILE }}'{{ OSS_FILE_KEY }}' -O {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }}"
args:
chdir: /opt/
creates: /opt/{{ OSS_URL }}/{{ OSS_FILE }}
register: download_file
#notify: restart {{ APP_NAME }}
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 程序包下载 CMD"
debug: var=download_file.cmd
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 改名"
shell: "new_file_name=`ls {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }} |awk -F'_' '{print $3}'` && echo ${new_file_name} && mv {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }} {{ APP_DIR }}/{{ APP_NAME }}/${new_file_name}"
args:
chdir: /opt/
creates: /opt/{{ OSS_URL }}/{{ OSS_FILE }}
register: move_file
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 改名 STDOUT"
debug: var=move_file.stdout
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 权限修改"
file:
path: "{{ APP_DIR }}/{{ APP_NAME }}"
state: directory
owner: "{{ DEPLOY_USER }}"
group: "{{ DEPLOY_USER }}"
recurse: yes
register: changed_permissions
- name: "APP {{ APP_NAME }} 权限修改 STDOUT"
debug: var=changed_permissions
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 服务重启"
shell: "echo {{ OSS_URL }}/{{ OSS_PATH }}/{{ OSS_FILE }} -O {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }}"
register: restart_service
notify: restart {{ APP_NAME }}
- name: "发布主机: {{ get_hostname.stdout }} APP {{ APP_NAME }} 服务重启 SDTOUT"
debug: var=restart_service.cmd
# 发布完成后的验证
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 进程状态"
shell: "echo {{ OSS_URL }}/{{ OSS_PATH }}/{{ OSS_FILE }} -O {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }}"
args:
chdir: /opt/
creates: /opt/{{ OSS_URL }}/{{ OSS_FILE }}
register: process_status
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 进程状态 STDOUT"
debug: var=process_status.stdout
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 服务状态"
shell: "echo {{ OSS_URL }}/{{ OSS_PATH }}/{{ OSS_FILE }} -O {{ APP_DIR }}/{{ APP_NAME }}/{{ OSS_FILE }}"
args:
chdir: /opt/
creates: /opt/{{ OSS_URL }}/{{ OSS_FILE }}
register: service_status
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 服务状态 STDOUT"
debug: var=service_status.stdout
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 接口状态"
shell: "curl -s -L %{http_code} {{ OSS_URL }} | grep \"Welcome!\" |awk '{print $1}'"
args:
chdir: /opt/
creates: /opt/{{ OSS_URL }}/{{ OSS_FILE }}
register: interface_status
- name: "发布主机: {{ get_hostname.stdout }} 验证 {{ APP_NAME }} 接口状态 STDOUT"
debug: var=interface_status.stdout
# 重启服务
handlers:
- name: restart {{ APP_NAME }}
service: name={{ APP_NAME }} state=restarted
执行参数
# 变量
ansible-playbook -C deploy.yaml -e "ding_url=ding.opendevops.cn app_name=tomcat app_dir=/tmp/deniss deploy_user=ubuntu, ding_token=qwerty&^%FDSFBSNFXZ&^%%"
# json
ansible-playbook -C deploy.yaml --extra-vars "{'app_name':'tomcat', 'deploy_user':'ubuntu', 'app_dir':'/tmp/deniss', 'ding_url':'ding.opendevops.cn', 'ding_token':'qwerty&^%FDSFBSNFXZ&^%%'}"