添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

模板templates

  • 文本文件,嵌套有脚本(使用模块编程语言编写)
  • Jinja2语言,使用字面量有下面形式
    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1,item2,…]
    元组:(item1,item2,…)
    字典:{key1:value1,key2:value2,…}
    布尔型:true/false
  • 算术运算:+,-,*,/,//,%,**
  • 比较操作:==,!=,>,>=,<,<=
  • 逻辑运算:and,or,not
  • 流表达式:for if when
  • templates功能:根据模块文件动态生成对应的配置文件
    templates文件必须存放于templates目录下,且命名为.j2结尾
    yml/yaml文件需和templates目录平级,目录结构如下:
    ./
    |——temnginx.yml
    |——templates
    |——nginx.conf.j2
#先在ansible节点安装nginx修改nginx配置文件,将内核数量给位自动获取
[root@ansible ~]# vim /etc/nginx/nginx.conf 
worker_processes  auto;
#然后将nginx配置文件cp到templates目录下并修改为.j2后缀
[root@ansible ~]# mkdir /etc/ansible/templates
[root@ansible ~]# cp /etc/nginx/nginx.conf /etc/ansible/templates/nginx.conf.j2
[root@ansible ansible]# cat testtemplate.yml 
- hosts: websrvs
  remote_user: root
  tasks:
    - name: cp nginx repo
      copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/
    - name: install nginx
      yum: name=nginx
    - name: cp template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf #因为这个文件放在templates目录下,所以这里不用写路径
    - name: start service
      service: name=nginx state=started enabled=yes
[root@ansible ansible]# ansible-playbook testtemplate.yml 
[root@ansible ansible]# ansible websrvs -m shell -a 'ss -ntpl| grep :80' 
192.168.100.20 | CHANGED | rc=0 >>
LISTEN     0      128          *:80                       *:*                   users:(("nginx",pid=3237,fd=6),("nginx",pid=3236,fd=6))
#nginx已经安装,看一下nginx的进程信息
[root@ansible ansible]# ansible websrvs -m shell -a 'ps aux |grep nginx'
192.168.100.20 | CHANGED | rc=0 >>
root       3423  0.0  0.1  46476  1144 ?        Ss   07:49   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx      3424  0.0  0.1  46880  1940 ?        S    07:49   0:00 nginx: worker process
nginx      3425  0.0  0.1  46880  1940 ?        S    07:49   0:00 nginx: worker process
root       3471  0.0  0.1 113172  1196 pts/1    S+   07:49   0:00 /bin/sh -c ps aux |grep nginx
root       3473  0.0  0.0 112704   940 pts/1    S+   07:49   0:00 grep nginx
# 这里有两个nginx进程,因为虚拟机的处理器数量设置的是两个,并且刚才修改的nginx配置文件内核数量为自动获取,所以这里是两个
#而在ansible节点处理器数量是一个,所以nginx的进程只有一个
[root@ansible ansible]# ps aux |grep nginx   
root       2017  0.0  0.0  46476   988 ?        Ss   07:51   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx      2018  0.0  0.1  46880  1944 ?        S    07:51   0:00 nginx: worker process
root       2020  0.0  0.0 112704   972 pts/0    S+   07:51   0:00 grep --color=auto nginx
#如果希望websrvs上的主机nginx进程是当前的两倍,auto自动获取无法实现,那该如何去做?
#用setup模块去查找cpu的变量名
[root@ansible ~]# ansible websrvs -m setup |grep "cpu"
        "ansible_processor_vcpus": 2, 
#然后编辑nginx.conf.j2文件
[root@ansible ~]# vim /etc/ansible/templates/nginx.conf.j2 
worker_processes  {{ ansible_processor_vcpus*2 }};
#将cpu数量*2
#因为刚才已经安装过nginx和启动服务了,这次只需把修改过的配置文件复制过去并且重启nginx使文件生效,这种就要用到handlers
[root@ansible ~]# vim /etc/ansible/testtemplate.yml 
- hosts: websrvs
  remote_user: root
  tasks:
    - name: cp nginx repo
      copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/
    - name: install nginx
      yum: name=nginx
    - name: cp template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf #因为这个文件放在templates目录下,所以这里不用写路径
      notify: restart service
    - name: start service
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart service
      service: name=nginx state=restarted
[root@ansible ansible]# ansible-playbook testtemplate.yml  
# 验证下nginx的进程数量
[root@ansible ansible]# ansible websrvs -m shell -a "ps aux |grep nginx"
192.168.100.20 | CHANGED | rc=0 >>
root       3911  0.0  0.1  46476  1148 ?        Ss   07:56   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx      3912  0.0  0.1  46880  1924 ?        S    07:56   0:00 nginx: worker process
nginx      3913  0.0  0.1  46880  1944 ?        S    07:56   0:00 nginx: worker process
nginx      3914  0.0  0.1  46880  1944 ?        S    07:56   0:00 nginx: worker process
nginx      3915  0.0  0.1  46880  1944 ?        S    07:56   0:00 nginx: worker process
root       3967  0.0  0.1 113172  1200 pts/1    S+   07:56   0:00 /bin/sh -c ps aux |grep nginx
root       3969  0.0  0.0 112704   940 pts/1    S+   07:56   0:00 grep nginx
#现在已经变成了四个进程
所以可以里模板根据当前系统的状态来生成对应的配置文件,比较灵活

when语句

when:
- 条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用jinja2的语法格式
- 在task后添加when子句即可使用条件测试;when语句支持jinja2表达式语法
tasks:
- name: shutdown redhat flavored systems
  command: /sbin/shutdown -h now
  when: ansible_os_family=="RedHat" #如果主机类型是RedHat类型就执行command模块的任务
#先看一下ansible_os_family这个变量
[root@ansible ~]# ansible all -m setup -a 'filter=ansible_os_family'
192.168.100.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
192.168.100.30 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
#如果要查看系统的版本就要用到distribution
[root@ansible ~]# ansible all -m setup -a 'filter="*distribution*"'
192.168.100.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7.5", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
192.168.100.30 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7.5", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
#也可以查看详细版本信息
[root@ansible ~]# ansible all -m setup -a 'filter=ansible_distribution_version'
192.168.100.30 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_version": "7.5", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
192.168.100.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_version": "7.5", 
        "discovered_interpreter_python": "/usr/bin/python"
    "changed": false
示例:根据centos7的详细版本号生产文件
然后修改template目录下的文件
把7.6的文件中的用户修改为daemon
7.7文件中的用户修改为bin
这种颜色代表跳过,当版本是7.6的时候就跳过106节点,当版本是7.7的时候就跳过了105节点
可以看到使用when执行判断已经执行成功了。

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制
	对迭代选项的引用,固定变量名为item
	要在task中使用with_items给定要迭代的元素列表
	列表格式:
示例:使用迭代的方法创建多个文件并安装多个包
[root@ansible ansible]# cat item.yml 
- hosts: all
  remote_user: root
  tasks:
    - name: create data directory
      file: name=/dat state=directory
    - name: create some files
      file: name=/data/{{ item }} state=touch #这里的item是一个特殊变量 代表下面列表中的一个个文件
      with_items:
        - file1
        - file2
    - name: install some packages
      yum: name={{ item }}
      with_items:
        - net-tools
        - lrzsz
[root@ansible ansible]# ansible-playbook item.yml 
[root@ansible ansible]# ansible all -m shell -a "ls -l /data"
192.168.100.20 | CHANGED | rc=0 >>
total 0
-rw-r--r--. 1 root root 0 Apr 24 04:13 aaa.jpg
lrwxrwxrwx. 1 root root 7 Apr 24 04:13 bbb.jpg -> aaa.jpg
-rw-r--r--. 1 root root 0 Apr 28 08:59 file1
-rw-r--r--. 1 root root 0 Apr 28 08:59 file2
-rw-r--r--. 1 root root 0 Apr 25 07:51 vsftpd.log
-rw-------. 1 test root 0 Apr 25 07:46 www81.test.log
192.168.100.30 | CHANGED | rc=0 >>
total 0
-rw-r--r--. 1 root root 0 Apr 28 08:59 file1
-rw-r--r--. 1 root root 0 Apr 28 08:59 file2
-rw-r--r--. 1 root root 0 Apr 24 23:38 newfile
[root@ansible ansible]# ansible all -m shell -a "rpm -q net-tools lrzsz"
192.168.100.30 | CHANGED | rc=0 >>
net-tools-2.0-0.25.20131004git.el7.x86_64
lrzsz-0.12.20-36.el7.x86_64
192.168.100.20 | CHANGED | rc=0 >>
net-tools-2.0-0.25.20131004git.el7.x86_64
lrzsz-0.12.20-36.el7.x86_64
#文件和包都是执行成功的,这样就实现了列表做循环
#迭代嵌套子变量
[root@ansible ansible]# cat item2.yml 
- hosts: all
  remote_user: root
  tasks:
    - name: create some groups 
      group: name={{ item }}
      with_items:
    - name: create some users
      user: name={{ item.name }} group={{ item.group }}
      with_items:
        - { name: 'user1', group: 'g1'}
        - { name: 'user2', group: 'g2'}
        - { name: 'user3', group: 'g3'}
[root@ansible ansible]# ansible-playbook item2.yml 
[root@ansible ansible]# ansible all -m shell -a 'getent passwd'
#部分信息
user1:x:1000:1000::/home/user1:/bin/bash
user2:x:1001:1001::/home/user2:/bin/bash
user3:x:1002:1002::/home/user3:/bin/bash

playbook中template for if

#示例:for循环
[root@ansible ansible]# cat testfor.yml 
- hosts: all
  remote_user: root
  vars:
    ports: # 这是个列表 里面存的是多个列表
  tasks:
    - name: cp conf
      template: src=for1.conf.j2 dest=/data/for1.conf
[root@ansible ansible]# vim templates/for1.conf.j2
{% for port in ports %}  #这里调用yml文件里定义的ports变量列表
server{
        listen {{ port }}    #第一次循环调用81,第二次循环调用82,以此类推...
{% endfor %}
[root@ansible ansible]# ansible-playbook testfor.yml 
[root@node-1 ~]# cat /data/for1.conf 
server{
        listen 81    
server{
        listen 82   
#还可以用字典的方式循环,结果和上面的一样,写法不一样
[root@ansible ansible]# cat testfor2.yml 
- hosts: all
  remote_user: root
  vars:
    ports: #列表下面存放字典,字典里存放键值对
      - listen_port: 81
      - listen_port: 82
  tasks:
    - name: cp conf
      template: src=for1.conf.j2 dest=/data/for1.conf
 [root@ansible ansible]# cat templates/for1.conf.j2 
{% for port in ports %} 
server{
        listen {{ port.listen_port }} #这里调用字典中的键值对  
{% endfor %}     
#这样写看不出有什么不通,但是这种可以在列表中存放多个元素,每个元素里面可以存放多个键值对
[root@ansible ansible]# cat testfor3.yml 
- hosts: all
  remote_user: root
  vars:
    ports: #列表下面存放多个列表元素 每个列表元素中有存放多个键值对
      - web1:
        port: 81
        name: web1
        rootdir: /data/website1
      - web2:
        port: 82
        name: web2
        rootdir: /data/website2
  tasks:
    - name: cp conf
      template: src=for3.conf.j2 dest=/data/for1.conf
[root@ansible ansible]# cat templates/for3.conf.j2 
{% for port in ports %}
server{
  listen {{ port.port }} #调用yml文件里面的ports列表中的port键值对
  servername {{ port.name }} #调用yml文件里面的ports列表中的name键值对
  documentroot {{ port.rootdir }} #调用yml文件里面的ports列表中的rootdir键值对
{% endfor %}
[root@ansible ansible]# ansible-playbook testfor3.yml 
[root@node-1 ~]# cat /data/for1.conf 
server{
  listen 81 #调用yml文件里面的ports列表中的port键值对
  servername web1 #调用yml文件里面的ports列表中的name键值对
  documentroot /data/website1 #调用yml文件里面的ports列表中的rootdir键值对
server{
  listen 82 #调用yml文件里面的ports列表中的port键值对
  servername web2 #调用yml文件里面的ports列表中的name键值对
  documentroot /data/website2 #调用yml文件里面的ports列表中的rootdir键值对
示例:if操作
[root@ansible ansible]# cat testif.yml 
- hosts: all
  remote_user: root
  vars:
    ports:
      - web1:
        port: 81
        rootdir: /data/website1
      - web2:
        port: 82
        name: web2
        rootdir: /data/website2
  tasks:
    - name: cp conf
      template: src=for4.conf.j2 dest=/data/for4.conf
[root@ansible ansible]# cat templates/for4.conf.j2 
{% for port in ports %}
server{
  listen{{ port.port }}
{% if port.name is defined %} #用来判断ports列表中的name键值对有没有定义,如果定义了就执行servername
  servername{{ port.name }}
{% endif %}
  documentroot{{ port.rootdir }}
{% endfor %}
[root@ansible ansible]# ansible-playbook testif.yml 
[root@node-1 ~]# cat /data/for4.conf 
server{
  listen81
  documentroot/data/website1
server{
  listen82
 #用来判断ports列表中的name键值对有没有定义,如果定义了就执行servername
  servernameweb2
  documentroot/data/website2
#可以看到第一个没有servername,第二个有servername
                                    运行Ansible剧本Github Action
 在选定主机上执行给定Ansible剧本的动作。
 如果在PATH有ansible-playbook命令可用,则它ansible-playbook在任何操作系统上运行。
- name : Run playbook
  uses : dawidd6/action-ansible-playbook@v2
  with :
    playbook : deploy.yml
    directory : ./
    key : ${{secrets.SSH_PRIVATE_KEY}}
    inventory : |
      [all]
      example.com
      [group1]
      example.com
    vault_password : ${{secrets.VAULT_PASSWORD}}
    options : |
      --limit group1
      --extra-vars hello=there
      --verbose
                                    Ansible Playbook捆绑包(APB)
 Ansible Playbook Bundle(APB)是一个轻量级的应用程序定义(元容器)。 它们用于定义复杂的应用程序,部署配置,部署和服务组,并将其部署到运行的集群。 通过利用的功能, 提供更多的功能和简单的配置。 APB具有以下功能:
 元数据包含在部署期间使用的必需/可选参数的列表。
 利用现有的Ansible角色/剧本投资。
 具有apb.yml中定义的命名剧本和元数据的目录下的操作。
 开发人员工具来驱动指导方法。
 轻松修改或扩展。
-创建Ansible Playbook捆绑包的分步教程
-Ansible Playbook套装的整体设计
-Ansible Playbook捆绑包的深入说明
apb cli工具的安装和使用
 Broker-有关运行更多信息
	Ansible是一个自动化统一配置管理工具,自动化主要体现在Ansible集成了丰富模块以及功能组件,可以通过一个命令完成一系列的操作,进而能减少重复性的工作和维护成本,可以提高工作效率。
1.连接插件connection plugins用于连接主机 用来连接被管理端
2.核心模块core modules连接主机实现操作, 它依赖于具体的模块来做具体的事情
3.自定义模块custom modules根据自己的需求编写具体的模块
4.插件plugins完成
                                    直接执行不行
[root@test shell]# ansible server9 -m shell -a "cat /etc/passwd|grep -v 'nologin\|shutdown\|sync\|halt'|awk -F : '{print $1}'"
server9 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bas...
                                    大家有没有一些疑惑,为什么在一些教程中,命令需要用单引号,我们也约定熟成地学习跟着教程来使用单引号,但我们有时候也会忘记到底是单引号还是双引号,于是不小心记成了双引号,发现也能达到我们想要的结果,于是乎——单引号和双引号到底有什么区别呢?
YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。字符串可以用双引号或单引号括起。
编写多行字符串有两种方式。可以使用管道符表示要保留字符串中的换行字符
[root@ansible pla
加载自己的配置文件,默认/etc/ansible/ansible.cfg
加载自己对应的模块文件,如command
通过ansible将模块命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/xxx.py文件
给文件+x执行
执行并返回结果
删除临时py文件,sleep 0退出
ansible 的执行状态
root@ubuntu20:~# grep -A 14 '\[colors\]' /
                                    文章目录一、yum安装ansible二、相关文件介绍`2.1.配置文件`a、/etc/ansible/ansible.cfg解释b、/etc/ansible/hosts格式`2.2.可执行文件`三、配置基于root用户Key的验证四、ansible命令执行过程五、执行状态六、常用模块`指定远程主机用户,并sudo到root用户`
参考视频:https://edu.51cto.com/lesson/306549
一、yum安装ansible
yum -y install epel-release
                                    Ansible概述
通过Ansible可以实现运维自动化,提高运维工程师的工作效率,减少人为的失误。Ansable通过本身集成非常丰富的模块实现各种管理任务,其自身模块超过上千个。
Ansible基于Python开发,运维工程师对其二次开发相对较容易。
Ansible丰富的内置模块,基本可以满足一切需求。
管理模式非常简单,一条命令可以影响上千台机器。
无客户端模式,底层通过SSH进行通信。
Ansible没有客户端,也不需要被管理主机添加代理程序,通过SSH完成底层通信,Ansible要
                                    文章目录简介旧循环语句(版本在2.5之前仅有的)with_items自定义with_list循环列表小练习:在受管主机中创建4个文件借助注册函数,多次执行循环中的不同命令for循环实现遍历嵌套列表的定义with_list关键字with_flattened关键字上述三种关键字的区别with_together关键字with_cartesian关键字with_indexed_items关键字单层列表时两...