1. Ansible Roles

ansilbe roles是自1.2版本引入的新特性,用于层次性、结构化地组织playbookroles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

1.1 roles目录结构

roles 官方目录结构,必须按如下方式定义。在每个目录中必须有 main.yml 文件,这些属于强制要求。

[root@xuzhichao /data/ansible/roles]$tree
.
├── playbooks.yml <==执行剧本
└── roles <==角色必须与执行剧本在同一级目录中
├── project <==项目名称
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── project1 <==另一个项目
  • tasks目录:角色需要执行的主任务文件放置在此目录中,默认的主任务文件名为main.yml,当调用角色时,默认会执行main.yml文件中的任务,你也可以将其他需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。
  • handlers目录:当角色需要调用handlers时,默认会在此目录中的main.yml文件中查找对应的handler
  • defaults目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,通常,defaults/main.yml文件中的变量都用于设置默认值,以便在你没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
  • vars目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
  • meta目录:如果你想要赋予这个角色一些元数据,则可以将元数据写入到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,你也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定,在之后会有一些实际的示例。
  • templates目录: 角色相关的模板文件可以放置在此目录中,当使用角色相关的模板时,如果没有指定路径,会默认从此目录中查找对应名称的模板文件。
  • files目录:角色可能会用到的一些其他文件可以放置在此目录中,比如,当你定义nginx角色时,需要配置https,那么相关的证书文件即可放置在此目录中。

当然,上述目录并不全是必须的,也就是说,如果你的角色并没有相关的模板文件,那么角色目录中并不用包含templates目录,同理,其他目录也一样,一般情况下,都至少会有一个tasks目录。

1.2 roles编写步骤

1.2.1 编写基本的roles

编写roles的步骤为:

  1. 创建 roles 项目目录结构,手动创建或使用 ansible-galaxy init test roles
  2. 编写 roles 的功能,也就是 tasks
  3. 最后 playbook 引用 roles 编写好的 tasks
  • 创建一个测试的roles目录,就叫roles_test1,并创建下面的子目录,最基本的子目录需要有tasks目录:

    [root@xuzhichao ~]# mkdir /data/ansible/roles
    [root@xuzhichao ~]# cd /data/ansible/roles
    [root@xuzhichao roles]# mkdir roles_test1
    [root@xuzhichao roles]# cd roles_test1
    [root@xuzhichao roles_test1]# mkdir tasks
  • 然后在tasks目录中编写相关的任务,在tasks目录中必须由一个main.yml文件,可以把需要编写的任务直接写到main.yml文件中,也可以写到其他文件中,然后在main.yml文件中通过include的方式引用这些文件。在tasks中的文件不需要写play部分,只需要写task部分。示例如下:

    [root@xuzhichao roles_test1]# cat tasks/main.yml
    - name: Print Vars
    debug:
    msg: "ansible_test_roles"

    或者:

    [root@xuzhichao roles_test1]# cat tasks/task1.yml
    - name: Print Vars
    debug:
    msg: "ansible_test_roles" [root@xuzhichao roles_test1]# cat tasks/main.yml
    - include: task1.yml
  • 写好task后,需要编写playbook调用rolesplaybook编写如下:

    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: roles_test1
  • 运行playbook

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************************
    ok: [localhost] TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "ansible_test_roles"
    } PLAY RECAP ****************************************************************************************************************************************************
    localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

1.2.2 roles的调用

playbook调用roles时,如何找到roles所在的目录呢?有以下几种方式:

  • playbook文件会在同级目录中寻找与调用的角色同名的roles,例如在上节中rolestest1.yml文件中调用了roles_test1这个角色,会自动在同级目录中找到roles_test1这个目录,并执行其中的tasks

    [root@xuzhichao roles]# ll
    total 4
    drwxr-xr-x 3 root root 19 Aug 7 16:57 roles_test1
    -rw-r--r-- 1 root root 46 Aug 7 17:14 rolestest1.yml
  • playbook文件还会寻找同级目录中的roles目录,执行roles目录中同名的角色项目,例如:

    [root@xuzhichao roles]# tree
    .
    ├── roles
    │   └── roles_test1
    │   └── tasks
    │   ├── main.yml
    │   └── task1.yml
    └── rolestest1.yml
  • 当前系统用户的家目录中的.ansible/roles目录,即 ~/.ansible/roles目录中。

  • 也可以修改ansible配置文件中定义的roles的路径,多个路径之间使用冒号隔开:

    [root@xuzhichao roles]# vim /etc/ansible/ansible.cfg
    roles_path = /etc/ansible/roles:/data/ansible/roles:/opt
  • playbook文件中直接写roles的绝对路径也可以调用roles

    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: /data/ansible/roles/roles_test1

1.2.3 roles中使用变量

  • 修改一下roles文件,引入变量:

    [root@xuzhichao roles]# cat roles_test1/tasks/task1.yml
    - name: Print Vars
    debug:
    msg: "{{ var1 }}"
  • 在调用这个角色时,则需要传入对应的变量,否则就会报错,调用上例角色的示例如下:

    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: roles_test1
    vars:
    var1: string1

    执行palybook,结果如下:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string1"
    }
  • 也可以为变量设置默认值,这样即使在调用角色时没有传入任何参数,也有默认的值可以使用,同时也不会在调用时因为没有传入对应变量而报错,需要在roles_test1目录中创建一个defaults目录,并且创建defaults/main.yml文件,defaults/main.yml文件内容如下:

    [root@xuzhichao roles]# cd roles_test1/
    [root@xuzhichao roles_test1]# mkdir defaults
    [root@xuzhichao roles_test1]# cat defaults/main.yml
    var1: string2
  • 此时运行palybook,结果仍然是string1,说明playbook文件中定义的变量值比defaults/main.yml文件定义的变量优先级高:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string1"
    }
  • 删除playbook文件中定义的变量后,运行playbook文件,显示的变量就是defaults/main.yml文件定义的变量:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string2"
    }
  • 接下来测试一下在vars/main.yml文件中定义变量,定义在vars/main.yml文件中的变量优先级比较高,难以被覆盖,我们测试一下定义在这个文件中的变量的优先级到底有多高,为了使效果更加明显,我们在defaults/main.yml文件和vars/main.yml文件,以及vars_files中同时定义var1变量,并为其赋值不同的值,如下:

    #在vars/main.yml中定义变量:
    [root@xuzhichao roles_test1]# cat vars/main.yml
    var1: string3 #在defaults/main.yml中定义变量:
    [root@xuzhichao roles_test1]# cat defaults/main.yml
    var1: string2 #在vars_files中定义变量:
    [root@xuzhichao roles]# cat /data/ansible/roles/vars.yml
    var1: string1 #定义playbook:
    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    vars_files: ./vars.yml
    roles:
    - role: roles_test1
    vars:
    var1: string4
  • 运行playbook文件,最终显示的变量是vars/main.yml中定义的变量:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string3"
    }
  • 变量优先级总结:前文中测试变量优先级时除了在命令行中定义的变量外,vars_files中定义的变量优先级最高,这样我们可以得出结论,变量的优先级最高的仍然是ansible-playbook命令行定义的变脸,其次是vars/main.yml的变量,其他的变量的定义方式的优先级不变。

  • 注意:在默认情况下,角色中的的变量是全局可访问的。就是说在同一个playbook中为一个role定义了变量,那么这个playbook中其他的role也会自动使用这个变量,例如:

    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: roles_test1
    vars:
    var1: string4 - role: roles_test2 [root@xuzhichao roles]# ansible-playbook rolestest1.yml PLAY [localhost] ********************************************************************************************************************************************** TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string4"
    } TASK [roles_test2 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string4"
    }

    如果想要解决上述问题,则可以将变量的访问域变成角色所私有的,如果想要将变量变成角色私有的,则需要设置/etc/ansible/ansible.cfg文件,将private_role_vars的值设置为yes,默认情况下,”private_role_vars = yes”是被注释掉的,将前面的注释符去掉皆可,设置完成后,再次执行上例中的rolestest1.yml 文件,输出结果如下:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml 
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string4"
    } TASK [roles_test2 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string2"
    } [root@xuzhichao roles]# cat roles_test2/defaults/main.yml
    var1: string2

1.2.4 多次调用同一个role

默认情况下,我们无法多次调用同一个角色,也就是说,如下playbook只会调用一次role角色:

# cat test.yml
- hosts: test
roles:
- role: testrole
- role: testrole

执行上例playbook会发现,testroledebug模块只输出了一次,如果想要多次调用同一个角色,有两种方法,如下:

  • 方法一:设置角色的allow_duplicates属性 ,让其支持重复的调用。

    # cat testrole/meta/main.yml
    allow_duplicates: true
  • 方法二:调用角色时,传入的参数值不同。

    # cat test.yml
    - hosts: test70
    roles:
    - role: testrole
    vars:
    testvar: "123"
    - role: testrole
    vars:
    testvar: "abc"

1.2.5 roles管理模板文件

前文中提到,roles中把所有的模板文件放置到templates目录中,我们来测试一下模板文件的使用。

  • 新增templates目录,建立模板文件:

    [root@xuzhichao roles]# mkdir roles_test1/templates
    
    [root@xuzhichao roles]# cat roles_test1/templates/temp.j2
    something in template;
    {{ template_var }}
  • tasks/main.yml文件如下:

    [root@xuzhichao roles]# cat roles_test1/tasks/main.yml
    - name: Print Vars
    debug:
    msg: "{{ var1 }}" - name: Copy Templates
    template:
    src: temp.j2
    dest: /tmp/temp
  • 变量文件如下:

    [root@xuzhichao roles]# cat roles_test1/vars/main.yml
    var1: string1
    template_var: tempvar
  • playbook文件如下:

    [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: roles_test1
  • 运行playbook文件:

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    ok: [localhost] => {
    "msg": "string1"
    } TASK [roles_test1 : Copy Templates] ***************************************************************************************************************************
    changed: [localhost] PLAY RECAP ****************************************************************************************************************************************************
    localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@xuzhichao roles]# cat /tmp/temp
    something in template;
    tempvar

1.2.6 roles管理handlers文件

如果想要在角色中使用一些handlers以便进行触发,则可以直接将对应的handler任务写入到handlers/main.yml文件中,示例如下:

  • 建立handlers目录,建立main.yml文件:

    [root@xuzhichao roles]# mkdir roles_test1/templates
    
    [root@xuzhichao roles]# mkdir roles_test1/handlers
    [root@xuzhichao roles]# cd roles_test1/handlers
    [root@xuzhichao handlers]# vim main.yml
    - name: test_handler
    debug:
    msg: "this is a test handler"
  • 为了能够更加简单的触发对应的handler,直接将tasks/main.yml中的debug任务的状态强行设置为”changed”,示例如下:

    [root@xuzhichao roles]# cat roles_test1/tasks/main.yml
    - name: Print Vars
    debug:
    msg: "{{ var1 }}"
    changed_when: true
    notify: test_handler - name: Copy Templates
    template:
    src: temp.j2
    dest: /tmp/temp [root@xuzhichao roles]# cat rolestest1.yml
    - hosts: localhost
    roles:
    - role: roles_test1
  • 运行playbook文件,直接触发handlers

    [root@xuzhichao roles]# ansible-playbook rolestest1.yml
    
    PLAY [localhost] **********************************************************************************************************************************************
    
    TASK [roles_test1 : Print Vars] *******************************************************************************************************************************
    changed: [localhost] => {
    "msg": "string1"
    } TASK [roles_test1 : Copy Templates] ***************************************************************************************************************************
    ok: [localhost] RUNNING HANDLER [roles_test1 : test_handler] ******************************************************************************************************************
    ok: [localhost] => {
    "msg": "this is a test handler"
    } PLAY RECAP ****************************************************************************************************************************************************
    localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

1.2.7 roles的依赖关系

roles 允许在使用时自动引入其他 rolerole 依赖关系存储在meta/main.yml 文件中。

例如: 安装 wordpress 项目时:

  1. 需要先确保 nginx php-fpmrole 都能正常运行;
  2. 然后在 wordpressrole 中定义,依赖关系;
  3. 依赖的 rolenginx 以及 php-fpm
  • wordpressrole中新建meta目录,编写main.yml文件:

    [root@m01 playbook]# cat /root/roles/wordpress/meta/main.yml
    ---
    dependencies:
    - { role: nginx }
    - { role: php-fpm }
  • wodpressplaybook中就不需要写安装nginxphp-fpmrole了,只写一个wordpress就可以了,安装wordpress之前会自动先部署了nginxphp-fpm

    [root@m01 playbook]# cat /root/roles/wordpress,yml
    ---
    - hosts: NginxWebs
    roles:
    - role: wordpress

1.2.8 roles的相互调用

roles中的各项目之间的文件是可以跨项目互相调用的。

跨项目调用时需要指明要调用的role的名称。

例如:同时部署了nginxapache两个项目,两个项目中使用了相同的index.html主页文件,这个蛀牙文件已经在nginx项目中定义过了。若此时需要在apache项目中引用,可以使用如下方式:

[root@localhost  /data/roles]$vim apache/tasks/html.yml      <==页面配置
- name: Copy Index File
copy:
src:roles/nginx/files/index.html #跨项目调用路径要写roles的名称
dest: /var/www/nginx/html/

1.3 roles部署nginx实例

  1. 首先创建项目目录nginx,并创建fileshandlersmetataskstemplatesvars等目录;用不到的目录可以创建为空目录,也可以不创建,用到时再创建也可以:

    [root@xuzhichao roles]# mkdir nginx/{tasks,templates,handlers,files,vars} -pv
  2. 编写nginx的任务功能:

    [root@xuzhichao nginx]# cat tasks/Install_Nginx.yml
    - name: Install Nginx Server
    yum:
    name: nginx
    state: present [root@xuzhichao nginx]# cat tasks/Configure_Nginx.yml
    - name: Configure Nginx Conf Files
    template:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    owner: "{{ item.user }}"
    group: "{{ item.group }}"
    mode: "{{ item.mode }}"
    loop:
    - { src: "nginx.conf.j2", dest: "/etc/nginx/nginx.conf", user: "root", group: "root", mode: "0644" }
    - { src: "ansible.web.conf.j2", dest: "/etc/nginx/conf.d/ansible.web.conf", user: "root", group: "root", mode: "0644" }
    notify: Restart Nginx Server [root@xuzhichao nginx]# cat tasks/Check_Configure.yml
    - name: Check Nginx Configure
    shell:
    cmd: "/usr/sbin/nginx -t"
    register: check_nginx
    changed_when:
    - check_nginx.stdout.find("ok")
    - false [root@xuzhichao nginx]# cat tasks/Init_Nginx.yml
    - name: Create Web Site Directory
    file:
    path: "{{ web_site_directory }}"
    state: directory
    owner: "{{ nginx_user }}"
    group: "{{ nginx_group }}"
    mode: "0755" - name: Init Nginx Server
    copy:
    src: "{{ nginxfile }}"
    dest: "{{ web_site_directory }}"
    owner: "{{ nginx_user }}"
    group: "{{ nginx_group }}"
    mode: "0644" [root@xuzhichao nginx]# cat tasks/Start_Nginx.yml
    - name: Start Nginx Server
    systemd:
    name: nginx
    state: started
    enabled: yes [root@xuzhichao nginx]# cat tasks/main.yml
    - include: Install_Nginx.yml
    - include: Configure_Nginx.yml
    - include: Check_Configure.yml
    - include: Init_Nginx.yml
    - include: Start_Nginx.yml
  3. 编写handlers文件:

    [root@xuzhichao nginx]# cat handlers/main.yml
    - name: Restart Nginx Server
    service:
    name: nginx
    state: restarted
  4. 编写模板文件:

    [root@xuzhichao nginx]# cat templates/nginx.conf.j2 
    
    user  {{ nginx_user }};
    worker_processes {{ ansible_processor_vcpus }}; events {
    worker_connections 1024;
    } http {
    include mime.types;
    default_type application/octet-stream; access_log logs/access.log main;
    log_format access_json '{ "@timestamp": "$time_iso8601", '
    '"remote_addr": "X-Forwarded_For", '
    '"referer": "$http_referer", '
    '"request": "$request", '
    '"status": $status, '
    '"bytes":$body_bytes_sent, '
    '"agent": "$http_user_agent", '
    '"x_forwarded": "$http_x_forwarded_for", '
    '"upstr_addr": "$upstream_addr",'
    '"upstr_host": "$upstream_http_host",'
    '"upstreamtime": "$upstream_response_time" }'; server_tokens off;
    fastcgi_cache_path /data/nginx/fastcgi_cache levels=1:1:1 keys_zone=fastcgi_cache:250m inactive=10m max_size=1g;
    sendfile on;
    keepalive_timeout 65; gzip on; include /etc/nginx/conf.d/*.conf;
    } [root@xuzhichao nginx]# cat templates/ansible.web.conf.j2
    server {
    listen 80;
    server_name {{ server_name }};
    charset utf-8,gbk;
    #防盗链
    valid_referers none blocked server_names *.b.com b.* ~\.baidu\. ~\.google\.; if ( $invalid_referer ) {
    return 403;
    } #浏览器图标
    location = /favicon.ico {
    root {{ web_site_directory }};
    } location / {
    root {{ web_site_directory }};
    index index.html index.php;
    }
    }
  5. 编写nginx主页文件:

    [root@xuzhichao nginx]# cat files/index.html
    <h1>ansible web site</h1>
  6. 编写变量文件:

    [root@xuzhichao nginx]# cat vars/main.yml
    web_site_directory: /data/nginx/ansible
    nginxfile: index.html
    nginx_user: nginx
    nginx_group: nginx
    server_name: ansible.web.com
  7. 编写playbook文件:

    [root@xuzhichao nginx]# cat nginx.yml
    - hosts: 192.168.20.23
    remote_user: root roles:
    - role: nginx
  8. 整个roles的目录结果如下:

    [root@xuzhichao nginx]# tree
    .
    ├── files
    │   └── index.html
    ├── handlers
    │   └── main.yml
    ├── nginx.yml
    ├── tasks
    │   ├── Check_Configure.yml
    │   ├── Configure_Nginx.yml
    │   ├── Init_Nginx.yml
    │   ├── Install_Nginx.yml
    │   ├── main.yml
    │   └── Start_Nginx.yml
    ├── templates
    │   ├── ansible.web.conf.j2
    │   └── nginx.conf.j2
    └── vars
    └── main.yml 5 directories, 12 files
  9. 运行palybook文件:

    [root@xuzhichao nginx]# ansible-playbook nginx.yml
    
    PLAY [192.168.20.23] ******************************************************************************************************************************************
    
    TASK [nginx : Install Nginx Server] ***************************************************************************************************************************
    ok: [192.168.20.23] TASK [nginx : Configure Nginx Conf Files] *********************************************************************************************************************
    ok: [192.168.20.23] => (item={u'dest': u'/etc/nginx/nginx.conf', u'src': u'nginx.conf.j2', u'group': u'root', u'user': u'root', u'mode': u'0644'})
    ok: [192.168.20.23] => (item={u'dest': u'/etc/nginx/conf.d/ansible.web.conf', u'src': u'ansible.web.conf.j2', u'group': u'root', u'user': u'root', u'mode': u'0644'}) TASK [nginx : Check Nginx Configure] **************************************************************************************************************************
    ok: [192.168.20.23] TASK [nginx : Create Web Site Directory] **********************************************************************************************************************
    ok: [192.168.20.23] TASK [nginx : Init Nginx Server] ******************************************************************************************************************************
    changed: [192.168.20.23] TASK [nginx : Start Nginx Server] *****************************************************************************************************************************
    changed: [192.168.20.23] PLAY RECAP ****************************************************************************************************************************************************
    192.168.20.23 : ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  10. 查看nginx主机的相关信息:

    [root@nginx03 ~]# cat /data/nginx/ansible/index.html
    <h1>ansible web site</h1> [root@nginx03 ~]# cat /etc/nginx/conf.d/ansible.web.conf
    server {
    listen 80;
    server_name ansible.web.com;
    charset utf-8,gbk;
    #防盗链
    valid_referers none blocked server_names *.b.com b.* ~\.baidu\. ~\.google\.; if ( $invalid_referer ) {
    return 403;
    } #浏览器图标
    location = /favicon.ico {
    root /data/nginx/ansible;
    } location / {
    root /data/nginx/ansible;
    index index.html index.php;
    }
    }

ansible系列(30)--ansible的role详解的更多相关文章

  1. 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...

  2. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  3. 构建安全的Xml Web Service系列之wse之错误代码详解

    原文:构建安全的Xml Web Service系列之wse之错误代码详解 WSE3.0现在还没有中文版的可以下载,使用英文版的过程中,难免会遇到各种各样的错误,而面对一堆毫无头绪的错误异常,常常会感到 ...

  4. [js高手之路] es6系列教程 - 对象功能扩展详解

    第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...

  5. [转帖]Linux系列之SAR命令使用详解

    Linux系列之SAR命令使用详解 sar是System Activity Reporter(系统活动情况报告)的缩写.这个工具所需要的负载很小,也是目前linux中最为全面的性能分析工具之一.此款工 ...

  6. SpringBoot系列(十二)过滤器配置详解

    SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...

  7. Ansible安装部署以及常用模块详解

    一.  Ansible 介绍Ansible是一个配置管理系统configuration management system, python 语言是运维人员必须会的语言, ansible 是一个基于py ...

  8. Ansible安装部署及常用模块详解

    Ansible命令使用 Ansible语法使用ansible <pattern_goes_here> -m <module_name> -a <arguments> ...

  9. ansible自动化运维工具使用详解

    一. ansible 简介 1. ansible ansible是新出现的 自动化 运维工具 , 基于Python研发 . 糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行 ...

  10. Ansible基础认识及安装使用详解(week5_day1_part1)--技术流ken

    Ansible简介 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批量 ...

随机推荐

  1. KingbaseES V8R6运维案例之---wal日志解析DDL操作

    ​ 案例说明: 通过sys_waldump解析DDL操作,获取DDL操作的日志条目具体内容. 适用版本: KingbaseES V8R3/R6 一.DDL事务操作对应的wal日志文件 # 查看当前on ...

  2. 【Java】使用位运算完成数组中两个变量交换位置

    1 /** 2 * 3 */ 4 package com.raliable.chapter_0; 5 /** 6 * @author : Administrator 7 * @date :2022年4 ...

  3. 2 URLEncode和Base64

    1. URLEncode和Base64 在我们访问一个url的时候总能看到这样的一种url https://www.sogou.com/web?query=%E5%90%83%E9%A5%AD%E7% ...

  4. #NIM游戏#CodeChef A Game With a Sheet of Paper

    SHGAME 分析 可以发现每次相当于去掉上下左右的若干行列,也就是 \(x-1,n-1-x,y-1,m-1-y\) 题目就转换成了取石子的问题,先手必胜当且仅当 \((x-1)\) xor \((n ...

  5. #矩阵乘法#洛谷 3702 [SDOI2017]序列计数

    题目链接 分析 考虑容斥,用总方案减去全是合数的方案数, 可以发现 \(n\) 很大,\(p\) 很小,直接用矩阵乘法转移即可 代码 #include <cstdio> #include ...

  6. C 语言文件读取全指南:打开、读取、逐行输出

    C 语言中的文件读取 要从文件读取,可以使用 r 模式: FILE *fptr; // 以读取模式打开文件 fptr = fopen("filename.txt", "r ...

  7. java集合源码详解

    一 Collection接口 1.List 1.1ArrayList 特点 1.底层实现基于动态数组,数组特点根据下表查找元素速度所以查找速度较快.继承自接口  Collection ->Lis ...

  8. 润乾报表与 ActiveReport JS 功能对比

    简介 润乾报表是用于报表制作的大型企业级报表软件,核心特点在于开创性地提出了非线性报表数学模型,采用了革命性的多源关联分片.不规则分组.自由格间运算.行列对称等技术,使得复杂报表的设计简单化,以往难以 ...

  9. k8s 深入篇———— 守护容器[九]

    前言 守护容器,也叫做deamonset, 只做整理 正文 顾名思义,DaemonSet 的主要作用,是让你在 Kubernetes 集群里,运行一个 Daemon Pod. 所以,这个 Pod 有如 ...

  10. redis 简单整理——HyperLogLog[十三]

    前言 简单介绍一下HyperLogLog. 正文 HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而 是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数 ...