Ansible playbook 简介

playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。
通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list ,而被控节点必须要完成。
也可以这么理解,playbook 字面意思,即剧本,现实中由演员按照剧本表演,在Ansible中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。

 

Ansible playbook使用场景

执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行的ad-hoc命令是不适合的,这时最好使用playbook。
就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。在你使用Ansible的过程中,你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。

Ansible playbook格式

1)格式简介

  playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。

  YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。首先学习了解一下YMAL的格式,对我们后面书写playbook很有帮助。以下为playbook常用到的YMAL格式:

  1、文件的第一行应该以 "---" (三个连字符)开始,表明YMAL文件的开始。

  2、在同一行中,#之后的内容表示注释,类似于shell,python和ruby。

  3、YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。

  4、同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。

  5、play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":"分隔表示,":"后面还要增加一个空格。

  下面是一个举例:

---
#安装与运行mysql服务
- hosts: node1
  remote_user: root
  tasks:
  
    - name: install mysql-server package
      yum: name=mysql-server state=present
    - name: starting mysqld service
      service: name=mysql state=started

我们的文件名称应该以.yml结尾,像我们上面的例子就是mysql.yml。其中,有三个部分组成:

host部分:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,

                  指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行 task 的过程中。

remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。

tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

使用ansible-playbook运行playbook文件,得到如下输出信息,输出内容为JSON格式。并且由不同颜色组成,便于识别。一般而言

| 绿色代表执行成功,系统保持原样
| 黄色代表系统代表系统状态发生改变
| 红色代表执行失败,显示错误输出

执行有三个步骤:1、收集facts 2、执行tasks 3、报告结果

2)核心元素

Playbook的核心元素:

Hosts:主机组;

Tasks:任务列表;

Variables:变量,设置方式有四种;

Templates:包含了模板语法的文本文件;

 

Handlers:由特定条件触发的任务;

3)基本组件

Playbooks配置文件的基础组件:

Hosts:运行指定任务的目标主机

remoute_user:在远程主机上执行任务的用户;

sudo_user:

tasks:任务列表

    格式:

    tasks:

      – name: TASK_NAME

       module: arguments

       notify: HANDLER_NAME

       handlers:

      – name: HANDLER_NAME

       module: arguments

          模块,模块参数:

            格式:

        (1) action: module arguments

        (2) module: arguments

        注意:shell和command模块后面直接跟命令,而非key=value类的参数列表;

handlers:任务,在特定条件下触发;接收到其它任务的通知时被触发;

  (1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;

  (2) 任务可以通过“tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用;

案例1

1,定义nginx.yaml

 

---
- hosts: web
  remote_user: root
  tasks:

    - name: install nginx
      yum: name=nginx state=present
    - name: copy nginx.conf
      copy: src=/ansibletest/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      notify: reload   #当nginx.conf发生改变时,通知给相应的handlers
      tags: reloadnginx   #打标签
    - name: start nginx service
      service: name=nginx state=started
      tags: startnginx   #打标签

  handlers:  #注意,前面没有-,是两个空格
    - name: reload
      service: name=nginx state=restarted  #为了在进程中能看出来

 

2,测试运行结果:

ansible-playbook nginx.yml
[root@localhost ansibletest]# ansible-playbook ./nginx.yaml 

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [install nginx] *********************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.118]
changed: [192.168.56.117]

TASK [copy nginx.conf] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [start nginx service] ***************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
192.168.56.117             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.56.118             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

 

 

 

3,测试标签

我们在里面已经打上了一个标签,所以可以直接引用标签。但是我们需要先把服务关闭,再来运行剧本并引用标签:

1 ansible web -m shell -a 'systemctl stop nginx'
2 ansible-playbook nginx.yml -t startnginx
[root@localhost ansibletest]# ansible web -m shell -a 'systemctl stop nginx'
192.168.56.117 | CHANGED | rc=0 >>

192.168.56.118 | CHANGED | rc=0 >>
[root@localhost ansibletest]# ansible-playbook ./nginx.yaml -t startnginx

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [start nginx service] ***************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

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

 

 

 

4,测试notify

我们还做了一个notify,来测试一下:

首先,它的触发条件是配置文件被改变,所以我们去把配置文件中的端口改一下:

[root@server ansible]# vim /ansibletest/nginx.conf
    listen       8080;

然后我们重新加载一下这个剧本:

[root@localhost ansibletest]# ansible-playbook ./nginx.yaml -t reloadnginx

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [copy nginx.conf] *******************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

RUNNING HANDLER [reload] *****************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
192.168.56.117             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.56.118             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

发现我们执行的就是reload段以及我们定义的notify部分。

我们来看一看我们的端口号:

[root@localhost ansibletest]# ansible web -m shell -a "netstat -tnlp | grep nginx"
192.168.56.118 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      23961/nginx: master 
tcp6       0      0 :::8080                 :::*                    LISTEN      23961/nginx: master 
192.168.56.117 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      24141/nginx: master 
tcp6       0      0 :::8080                 :::*                    LISTEN      24141/nginx: master 

4) variables 部分

variables变量,有四种定义方法,现在我们就来说说这四种定义方法:

1,facts :可直接调用

上一篇中,我们有说到setup这个模块,这个模块就是通过调用facts组件来实现的。我们这里的variables也可以直接调用facts组件。

具体的facters我们可以使用setup模块来获取,然后直接放入我们的剧本中调用即可。

---
- hosts:webservers
  tasks:
    - debug:
      msg: {{group_names}}                     #打印ansible的host组
    - debug:
      msg: {{inventory_hostname}}              #打印详细的host主机
    - debug:
  msg: {{ansible_hostname}}                        #配合gather_facts: yes     开启收集系统信息

系统变量可以通过setup模块查看和获取

1 ansible web -m setup

由于输出信息很多这里不显示出来,有兴趣可以自己去查看试试。

2,用户自定义变量

通过命令行传入

  ansible-playbook命令的命令行中的-e VARS, --extra-vars=VARS,这样就可以直接把自定义的变量传入。

在playbook中定义变量

  我们也可以直接在playbook中定义我们的变量:

vars:
    var1: value1
    var2: value2

 

3,通过roles传递变量

具体的,我们下文中说到 roles 的时候再详细说明。这里是传送带

4,Host Inventory

我们也可以直接在主机清单中定义。

定义的方法如下:

向不同的主机传递不同的变量:

192.168.56.117 var1=value1 var2=value2

向组中的主机传递相同的变量:

[web]
192.168.56.117
192.168.56.118
[web:vars] var1=value1
var2=value2

5) 模板 Template

模板是一个文本文件,嵌套有脚本(使用模板编程语言编写)。

Jinja2:Jinja2是python的一种模板语言,以Django的模板语言为原本。

模板支持:

  字符串:使用单引号或双引号;

  数字:整数,浮点数;

  列表:[item1, item2, ...]

  元组:(item1, item2, ...)

  字典:{key1:value1, key2:value2, ...}

  布尔型:true/false

  算术运算:

    +, -, *, /, //, %, **

  比较操作:

    ==, !=, >, >=, <, <=

  逻辑运算:

    and, or, not

 

通常来说,模板都是通过引用变量来运用的。

举例:

我们直接把之前定义的/ansibletest/nginx.conf 复制一份命名为nginx.conf.j2,然后编辑一下,就可以定义成我们的模板文件了:

 

cp nginx.conf nginx.conf.j2
vim nginx.conf.j2

 

内容修改为如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

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;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       {{nginxport}} default_server;
        listen       [::]:{{nginxport}} 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 = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

}

我们将端口号位置改为{{nginxport}}

修改nginx.yaml文件

修改内容如下:

---
- hosts: web
  remote_user: root
  vars:
    rpmname: nginx
    nginxport: 8080
  tasks:

    - name: install nginx
      yum: name=nginx state=present
    - name: copy nginx.conf
      template: src=/ansibletest/{{rpmname}}.conf.j2 dest=/etc/nginx/nginx.conf #注意这里我们把copy改成了template
      notify: reload
      tags: reloadnginx
    - name: start nginx service
      service: name=nginx state=started
      tags: startnginx   
  handlers:
    - name: reload
      service: name=nginx state=restarted

执行脚本:

[root@localhost ansibletest]# ansible-playbook ./nginx.yaml

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [install nginx] *********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.118]
ok: [192.168.56.117]

TASK [copy nginx.conf] *******************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.118]
changed: [192.168.56.117]

TASK [start nginx service] ***************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.118]
changed: [192.168.56.117]

RUNNING HANDLER [reload] *****************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
192.168.56.117             : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.56.118             : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

查看端口是否更改

[root@localhost ansibletest]# ansible web -m shell -a "netstat -tnlp | grep nginx"
192.168.56.117 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      27246/nginx: master 
tcp6       0      0 :::8080                 :::*                    LISTEN      27246/nginx: master 
192.168.56.118 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      26995/nginx: master 
tcp6       0      0 :::8080                 :::*                    LISTEN      26995/nginx: master 

可以看到端口号已经更改成8080

6)条件执行任务和循环执行任务

1,条件执行所用的命令是when, 当条件满足时才会执行相对应的任务

我们来看看下面的例子:

编写condation.yaml playbook

---
- hosts: web
  remote_user: root
  tasks:

    - name: task1
      debug: msg="task1 executed, major-version={{ansible_distribution_major_version}}"
      when: ansible_distribution_major_version=="7"
    - name: task2
      debug: msg="task2 executed, major-version={{ansible_distribution_major_version}}"
      when: ansible_distribution_major_version=="6"
    - name: task3
      debug: msg="task3 executed, major-version={{ansible_distribution_major_version}}"
      when: ansible_distribution_major_version=="5"

执行此playbook

[root@localhost ansibletest]# ansible-playbook ./condation.yaml 

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.118]
ok: [192.168.56.117]

TASK [task1] *****************************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117] => {
    "msg": "task1 executed, major-version=7"
}
ok: [192.168.56.118] => {
    "msg": "task1 executed, major-version=7"
}

TASK [task2] *****************************************************************************************************************************************************************************************************************************************************************
skipping: [192.168.56.117]
skipping: [192.168.56.118]

TASK [task3] *****************************************************************************************************************************************************************************************************************************************************************
skipping: [192.168.56.117]
skipping: [192.168.56.118]

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

可以看到我们的版本是7,所以跳过了task2,task3两个任务,只执行了task1

2,循环执行任务

对迭代项的引用,固定变量名为"item",而后,要在task中使用with_items给定要迭代的元素列表;

来看个例子;

编写iteration.yaml playbook

---
- hosts: web
  remote_user: root
  tasks:

    - name: task1
      debug: msg="iterration {{item}} executed !"
      with_items:
      - item1
      - item2
      - item3

执行结果:

[root@localhost ansibletest]# ansible-playbook ./iterration.yaml 

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [task1] *****************************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117] => (item=item1) => {
    "msg": "iterration item1 executed !"
}
ok: [192.168.56.117] => (item=item2) => {
    "msg": "iterration item2 executed !"
}
ok: [192.168.56.117] => (item=item3) => {
    "msg": "iterration item3 executed !"
}
ok: [192.168.56.118] => (item=item1) => {
    "msg": "iterration item1 executed !"
}
ok: [192.168.56.118] => (item=item2) => {
    "msg": "iterration item2 executed !"
}
ok: [192.168.56.118] => (item=item3) => {
    "msg": "iterration item3 executed !"
}

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

可以看到item1,2,3都执行了 

7)字典

以上我们学习到task可以根据with_items的指定元素集,可以做循环执行某一任务的功能,其实字典功能也是也是和循环功能类似,唯一的不同是他可以指定item的 内部属性,下面我们通过例子讲解一下

编写dictionaries.yaml playbook文件

---
- hosts: web
  remote_user: root
  tasks:
    - name: task1
      debug: msg="name {{item.name}},age {{item.age}}"
      with_items:
      - {name : 'zhangsan',age : '18'}  #注意这里的书写格式,:之间必须要有空格,后面的值也必须得用单引号,不能用双引号
      - {name : 'lisi',age : '19'}
      - {name : 'wangwu',age : '20'}

执行结果:

[root@localhost ansibletest]# ansible-playbook ./dictionaries.yaml 

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117]
ok: [192.168.56.118]

TASK [task1] *****************************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.117] => (item={u'age': u'18', u'name': u'zhangsan'}) => {
    "msg": "name zhangsan,age 18"
}
ok: [192.168.56.117] => (item={u'age': u'19', u'name': u'lisi'}) => {
    "msg": "name lisi,age 19"
}
ok: [192.168.56.118] => (item={u'age': u'18', u'name': u'zhangsan'}) => {
    "msg": "name zhangsan,age 18"
}
ok: [192.168.56.117] => (item={u'age': u'20', u'name': u'wangwu'}) => {
    "msg": "name wangwu,age 20"
}
ok: [192.168.56.118] => (item={u'age': u'19', u'name': u'lisi'}) => {
    "msg": "name lisi,age 19"
}
ok: [192.168.56.118] => (item={u'age': u'20', u'name': u'wangwu'}) => {
    "msg": "name wangwu,age 20"
}

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

这就是数据字典的功能和用法,每一个元素可以包含多个属性,不只是两个,这里只是测试

8)角色定制

1,简介:

对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。

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

2,目录解释:

1 files/:存储由copy或script等模块调用的文件;
2 tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;
3 handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;
4 vars/:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;
5 templates/:存储由template模块调用的模板文本;
6 meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;
7 default/:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;

3,测试;

下面我们来通过一个案例来介绍角色定制的用法

这个案例是通过角色定制的方式来为每一个被管节点创建go的运行环境,废话不多说开干

step1,创建目录

[root@localhost ansibletest]# mkdir -pv ./roles/gosetup/{files,templates,vars,tasks,handlers,meta,default}
mkdir: 已创建目录 "./roles"
mkdir: 已创建目录 "./roles/gosetup"
mkdir: 已创建目录 "./roles/gosetup/files
mkdir: 已创建目录 "./roles/gosetup/templates"
mkdir: 已创建目录 "./roles/gosetup/vars"
mkdir: 已创建目录 "./roles/gosetup/tasks"
mkdir: 已创建目录 "./roles/gosetup/handlers"
mkdir: 已创建目录 "./roles/gosetup/meta"
mkdir: 已创建目录 "./roles/gosetup/default"
[root@localhost roles]# tree -d
.
└── gosetup
    ├── default
    ├── files
    ├── handlers
    ├── meta
    ├── tasks
    ├── templates
    └── vars

step2,将所需要的文件放到files目录下面

[root@localhost roles]# tree
.
└── gosetup
    ├── default
    ├── files
    │   ├── go1.15.6.linux-amd64.tar.gz
    │   └── goenv.sh

step3, 编写tasks下的main.yaml文件,文件内容如下:

- name: copy go package 
  copy: src=go1.15.6.linux-amd64.tar.gz dest=/usr/local/
- name: copy goenv.sh
  copy: src=goenv.sh dest=/etc/profile.d/
- name: unzip go package
  shell: "cd /usr/local;tar -xvf ./go1.15.6.linux-amd64.tar.gz"
- name: create gopath directory
  file: path=/usr/local/gopath state=directory
- name: refresh the environment variables
  shell: "source /etc/profile"
- name: get result of gosetup
  shell: "go version;export"
[root@localhost roles]# tree
.
└── gosetup
    ├── default
    ├── files
    │   ├── go1.15.6.linux-amd64.tar.gz
    │   └── goenv.sh
    ├── handlers
    ├── meta
    ├── tasks
    │   └── main.yaml
    ├── templates
    └── vars

现在准备工作已经做完,开始编写playbook 文件

step4, 进入roles目录的上级目录创建文件roles.yaml playbook文件,文件内容如下:

- hosts: web
  remote_user: root
  roles:
    - gosetup

因为大部分内容我们都存放在了roles里,所以playbook文件的内容比较少

下面我们来执行这个playbook文件

[root@localhost ansibletest]# ansible-playbook ./roles.yaml 

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

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [192.168.56.118]
ok: [192.168.56.117]

TASK [gosetup : copy go package] *********************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.118]
changed: [192.168.56.117]

TASK [gosetup : copy goenv.sh] ***********************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

TASK [gosetup : unzip go package] ********************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

TASK [gosetup : create gopath directory] *************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

TASK [gosetup : refresh the environment variables] ***************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

TASK [get result of gosetup] *************************************************************************************************************************************************************************************************************************************************
changed: [192.168.56.117]
changed: [192.168.56.118]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
192.168.56.117             : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.56.118             : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

显示已经成功执行。我们再测试下看执行结果是不是符合我们的预期

[root@localhost ansibletest]# ansible web -m  shell -a "go version;echo 'GOPATH is $GOPATH'"
192.168.56.117 | CHANGED | rc=0 >>
go version go1.15.6 linux/amd64
GOPATH is /usr/local/gopath
192.168.56.118 | CHANGED | rc=0 >>
go version go1.15.6 linux/amd64
GOPATH is /usr/local/gopath

从以上结果可以看出我们的go运行环境已经安装成功

 

 

 

 

 

 

参考文章:

https://www.bookstack.cn/read/ansible-first-book/advance-playbook-tamplatezhong_shi_yong_bian_liang.md

posted on 2020-12-24 14:33  EZgod  阅读(484)  评论(0编辑  收藏  举报