注意:对于本文中出现的 { { } }和{ % % },前后 “{ {“ 以及 “{ %” 中间在实际操作中是没有空格的,由于hexo模板渲染问题,导致不得不加空格

YAML

介绍

  • YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括: XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者

  • YAML Ain’t Markup Language,即YAML不是XML。不过,在开发的这种语言时, YAML的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)

  • 特性

    • YAML的可读性好
    • YAML和脚本语言的交互性好
    • YAML使用实现语言的数据类型
    • YAML有一个一致的信息模型
    • YAML易于实现
    • YAML可以基于流来处理
    • YAML表达能力强,扩展性好
  • 更多的内容及规范参见:http://www.yaml.org

语法

  • 在单一档案中,可用连续三个连字号(-)区分多个档案。另外,还有选择性的连续三个点号( … )用来表示档案结尾

  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能

  • 使用#号注释代码

  • 缩进必须是统一的,不能空格和tab混用

  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的

  • YAML文件内容是区别大小写的,k/v的值均需大小写敏感

  • 多个k/v可同行写也可换行写,同行使用,分隔

  • v可是个字符串,也可是另一个列表

  • 一个完整的代码块功能需最少元素需包括 name 和 task

  • 一个name只能包括一个task

  • YAML文件扩展名通常为yml或yaml

  • List:列表,其所有元素均使用“-”打头

    示例:

    1
    2
    3
    4
    5
    # A list of tasty fruits
    -Apple
    -Orange
    -Strawberry
    -Mango
  • Dictionary:字典,通常由多个key与value构成

    示例:

    1
    2
    3
    4
    5
    ---
    # An employee record
    name: Example Developer
    job: Developer
    skill: Elite

    也可以将key:value放置于{}中进行表示,用,分隔多个key:value

    示例:

    1
    2
    3
    ---
    # An employee record
    {name: Example Developer, job: Developer, skill: Elite}
  • YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来代表,Map里的键值对用”:”分隔

    示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    name: John Smith 
    age: 41
    gender: Male
    spouse:
    name: Jane Smith
    age: 37
    gender: Female
    children:
    - name: Jimmy Smith
    age: 17
    gender: Male
    - name: Jenny Smith
    age: 13
    gender: Female

三种常见的数据交换格式

image-20200504191555869

Playbook

核心元素

  • Host 执行的远程主机列表

  • Task 任务集

  • Variables 内置变量或自定义变量在playbook中调用

  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件

  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行, 否则不执行

  • tags 标签指定某条任务执行,用于选择运行playbook中的部分代码。ansible 具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

    ansible-playbook -t tagsname useradd.yml

基础组件

  • Hosts:

    • playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中

    • 可以是如下形式:

      1
      2
      3
      4
      - - one.example.com
      one.example.com:two.example.com
      192.168.1.50
      192.168.1.*
    • Websrvs:dbsrvs 或者,两个组的并集

    • Websrvs:&dbsrvs 与,两个组的交集

    • webservers:!phoenix 在websrvs组,但不在dbsrvs组
      示例: - host: websrvs:dbsrvs

  • remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

    1
    2
    3
    4
    5
    6
    7
    8
    - host: websrvs
    remote_user:root
    task:
    - name: test conection
    ping:
    remote_user: xxx
    sudo: yes 默认sudo为root
    sudo_user:kinmfer sudo为kinmfer
  • task列表和action

    • play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务
    • task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
    • 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出
  • tasks:任务列表

    • 两种格式:

      1. action: module arguments
      2. module: arguments 建议使用
      • 注意:shell和command模块后面跟命令,而非key=value
    • 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers

    • 任务可以通过”tags“打标签,可在ansible-playbook命令上使用-t指定进行调用示例:

      1
      2
      3
      tasks:
      - name: disable selinux
      command: /sbin/setenforce 0
    • 如果命令或脚本的退出码不为零,可以使用如下方式替代

      1
      2
      3
      tasks:
      - name: run this command and ignore the result
      shell: /usr/bin/somecommand || /bin/true
    • 或者使用ignore_errors来忽略错误信息

      1
      2
      3
      4
      tasks:
      - name: run this command and ignore the result
      shell: /usr/bin/somecommand
      ignore_errors: True

      运行playbook

  • 运行playbok的方式
    ansible-playbook <filename.yml> ... [options]

  • 常见选项

    • –syntax-check 检查语法格式
    • –check -C 只检测可能会发生的改变,但不真正执行操作
    • –list-hosts 列出运行任务的主机
    • –list-tags 列出tag
    • –list-task 列出task
    • –limit 主机列表 只针对主机列表中的主机执行
    • -v -vv -vvv 显示过程
    • -e 在Playbook中引入外部参数变量
    • -t –tags 指定执行该tags的任务
    • –skip-tags 跳过指定的tags任务
  • 示例

    • ansible-playbook file.yml --check 只检测
    • ansible-playbook file.yml
    • ansible-playbook file.yml --limit websrvs

示例

  • sysuser.yml

    1
    2
    3
    4
    5
    6
    7
    8
    - hosts: all  
    remote_user: root
    gather_facts: no # 不收集信息
    tasks:
    - name: create mysql user
    user: name=mysql system=yes uid=36
    - name: create a group
    group: name=httpd system=yes
  • httpd.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    - hosts: websrvs  
    remote_user: root
    gather_facts: no # 不收集信息
    tasks:
    - name: Install httpd
    yum: name=httpd state=present
    - name: Install configure file
    copy: src=files/httpd.conf dest=/etc/httpd/conf/
    - name: start service
    service: name=httpd state=started enabled=yes
  • nginx.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    - hosts: websrvs  
    remote_user: root
    tasks:
    - name: add group nginx
    group: name=nginx state=present
    - name: add user nginx
    user: name=nginx state=present group=nginx
    - name: Install Nginx
    yum: name=nginx state=present
    - name: Start Nginx
    service: name=nginx state=started enabled=yes

    handlers和notify

  • Handlers

    是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作

  • Notify

    此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。 在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: websrvs  
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
- name: ensure apache is running
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- hosts: webnodes  
vars:
http_port: 80
max_clients: 256
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: ensure apache is running
service: name=httpd state=started
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
handlers:
- name: restart apache
service: name=httpd state=restarted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- hosts: websrvs  
remote_user: root
tasks:
- name: add group nginx
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: config
copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
notify:
- Restart Nginx
- Check Nginx Process
handlers:
- name: Restart Nginx
service: name=nginx state=restarted enabled=yes
- name: Check Nginx process
shell: killall -0 nginx > /tmp/nginx.log

tags

1
2
3
4
5
6
7
8
9
10
11
- hosts: websrvs  
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: conf
- name: start httpd
service tags: service
service: name=httpd state=started enabled=yes

ansible-playbook –t conf httpd.yml


1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: testsrv  
remote_user: root
tags: inshttpd
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: rshttpd
notify: restart httpd
handlers:
- name: restart httpd
service: name=httpd status=restarted

ansible-playbook –t rshttpd httpd2.yml

ansible-playbook –-skip-tags rshttpd httpd2.yml

变量

  • 变量来源:

    1. ansible setup facts 远程主机的所有变量都可直接调用

    2. 在/etc/ansible/hosts中定义

      普通变量:主机组中主机单独定义,优先级高于公共变量

      公共(组)变量:针对主机组中所有主机定义统一变量

    3. 通过命令行指定变量,优先级最高

      ansible-playbook –e varname=value

    4. 在playbook中定义

      1
      2
      3
      vars:
      -var1: value1
      -var2: value2
    5. 在独立的变量YAML文件中定义

    6. 在role中定义

  • 变量命名

    变量名仅能由字母、数字和下划线组成,且只能以字母开头

  • 变量定义:key=value

    示例:http_port=80

  • 变量调用方式:

    • 通过{ { variable_name } } 调用变量,且变量名前后必须有空格,有时用 “{ { variable_name } }”才生效

    • ansible-playbook –e 选项指定

      ansible-playbook test.yml -e "hosts=www user=xxx"

  • 主机变量

    可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用

    示例:

    1
    2
    [websrvs]
    www1.kinmfer.com http_port=80 maxRequestsPerChild=808 www2.kinmfer.com http_port=8080 maxRequestsPerChild=909
  • 组变量

    组变量是指赋予给指定组内所有主机上的在playbook中可用的变量

    示例 :

    1
    2
    3
    4
    5
    [websrvs]
    www1.xxx.com www2.xxx.com
    [websrvs:vars]
    ntp_server=ntp.xxx.com
    nfs_server=nfs.xxx.com
  • 命令行指定变量:

    ansible websvrs –e http_port=8000 –m hostname –a ‘name={ { hname } }{ { mark } }{ { http_port } }’

  • 使用变量文件

    cat vars.yml

    1
    2
    var1: httpd  
    var2: nginx

    cat var.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - hosts: web  
    remote_user: root
    vars_files:
    - vars.yml
    tasks:
    - name: create httpd log
    file: name=/app/{ { var1 } }.log state=touch
    - name: create nginx log
    file: name=/app/{ { var2 } }.log state=touch
  • setup变量

    1
    2
    3
    4
    5
    - host: websrvs
    remote_user:root
    task:
    - name: create log file
    file: name=/var/log/ {{ ansible_fqdn }} stae=touch

    获取内置变量方法:
    ansible oldboy -m setup -a "filter=ansible_hostname"

    常见主机信息:

    变量 含义
    ansible_all_ipv4_addresses: 仅显示ipv4的信息。
    ansible_devices: 仅显示磁盘设备信息。
    ansible_distribution: 显示是什么系统,例:centos,suse等。
    ansible_distribution_major_version: 显示是系统主版本。
    ansible_distribution_version: 仅显示系统版本。
    ansible_machine: 显示系统类型,例:32位,还是64位。
    ansible_eth0: 仅显示eth0的信息。
    ansible_hostname: 仅显示主机名。
    ansible_kernel: 仅显示内核版本。
    ansible_lvm: 显示lvm相关信息。
    ansible_memtotal_mb: 显示系统总内存。
    ansible_memfree_mb: 显示可用系统内存。
    ansible_memory_mb: 详细显示内存情况。
    ansible_swaptotal_mb: 显示总的swap内存。
    ansible_swapfree_mb: 显示swap内存的可用内存。
    ansible_mounts: 显示系统磁盘挂载情况。
    ansible_processor: 显示cpu个数(具体显示每个cpu的型号)。
    ansible_processor_vcpus: 显示cpu个数(只显示总的个数)。

示例

var.yml

1
2
3
4
5
- hosts: websrvs  
remote_user: root
tasks:
- name: install package
yum: name={ { pkname } } state=present

ansible-playbook –e pkname=httpd var.yml


var.yml

1
2
3
4
5
6
7
8
9
10
- hosts: websrvs  
remote_user: root
vars:
- username: user1
- groupname: group1
tasks:
- name: create group
group: name={ { groupname } } state=present
- name: create user
user: name={ { username } } state=present

ansible-playbook var.yml
ansible-playbook -e "username=user2 groupname=group2” var2.yml

when

  • 条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法 格式

  • when语句

    在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法

  • 示例:

    1
    2
    3
    4
    tasks:
    - name: "shutdown RedHat flavored systems"
    command: /sbin/shutdown -h now
    when: ansible_os_family == "RedHat"
  • when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者success)运行后面指定的语句,可使用类似如下形式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    tasks:
    - command: /bin/false
    register: result
    ignore_errors: True
    - command: /bin/something
    when: result|failed
    - command: /bin/something_else
    when: result|success
    - command: /bin/still/something_else
    when: result|skipped
  • 此外,when语句中还可以使用facts或playbook中定义的变量

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: websrvs  
remote_user: root
tasks:
- name: add group nginx
tags: user
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: restart Nginx
service: name=nginx state=restarted
when: ansible_distribution_major_version == “6”

1
2
3
4
5
6
7
tasks:
- name: install conf file to centos7
template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "6"

with_items

  • 迭代:当有需要重复性执行的任务时,可以使用迭代机制

    • 对迭代项的引用,固定变量名为”item“
    • 要在task中使用with_items给定要迭代的元素列表
    • 列表格式:
      • 字符串
      • 字典
  • ansible的循环机制还有更多的高级功能,具体请参见官方文档

    http://docs.ansible.com/playbooks_loops.html

示例

1
2
3
4
5
name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2

上面语句的功能等同于下面的语句:

1
2
3
4
name: add user testuser1
user: name=testuser1 state=present groups=wheel
name: add user testuser2
user: name=testuser2 state=present groups=wheel

with_items中可以使用元素还可为hashes

1
2
3
4
5
name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
-{ name: 'testuser1', groups: 'wheel' }
-{ name: 'testuser2', groups: 'root' }

将多个文件进行copy到被控端

1
2
3
4
5
6
7
8
- hosts: testsrv  
remote_user: root
tasks:
- name: Create rsyncd config
copy: src={{ item }} dest=/etc/{{ item }}
with_items:
- rsyncd.secrets
- rsyncd.conf

迭代嵌套自变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- hosts:websrvs  
remote_user: root
tasks:
- name: add some groups
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user1', group: 'group1' }
- { name: 'user2', group: 'group2' }
- { name: 'user3', group: 'group3' }

字典 with_items

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: 使用ufw模块来管理哪些端口需要开启 
ufw:
rule: “{{ item.rule }}”
port: “{{ item.port }}”
proto: “{{ item.proto }}”
with_items:
- { rule: ‘allow’, port: 22, proto: ‘tcp’ }
- { rule: ‘allow’, port: 80, proto: ‘tcp’ }
- { rule: ‘allow’, port: 123, proto: ‘udp’ }
- name: 配置网络进出方向的默认规则
ufw:
direction: "{{ item.direction }}" policy: "{{ item.policy }}" state: enabled
with_items:
- { direction: outgoing, policy: allow }
- { direction: incoming, policy: deny }

基础元素

  • Facts:是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts,可使用如下命令进行

    ansible websrvs -m setup

  • 通过命令行传递变量

    在运行playbook的时候也可以传递一些变量供playbook使用

    示例:

    ansible-playbook test.yml -e "hosts=www user=kinmfer"

  • register

    把任务的输出定义为变量,然后用于其他任务

    示例 :

    1
    2
    3
    4
    5
    6
    7
    tasks:
    - name: check server port
    shell: netstat -lntup
    register: get_server_port
    ignore_errors: True
    - name: display port info
    debug: msg={ { get_server_port.stdout_lines } }

    剧本整合

方式一:include_tasks: f1.yml

1
2
3
4
5
hosts: all
remote_user: root
tasks:
- include_tasks: f1.yml
- include_tasks: f2.yml

方式二:include: f1.yml

1
2
- include:f1.yml	
- include:f2.yml

方式三:import_playbook:

1
2
3
4
5
6
7
[root@m01 ansible-playbook]# cat main.yml 
- import_playbook: base.yml
- import_playbook: rsync.yml
- import_playbook: nfs.yml
- import_playbook: oxxx.yml
- import_playbook: rsync.yml
- import_playbook: nfs.yml

常见错误

  1. 剧本语法规范是否符合(空格 冒号 短横线)
  2. 剧本中模块使用是否正确
  3. 剧本中一个name标识下面只能写一个模块任务信息
  4. 剧本中尽量不要大量使用shell模块

模板template

注意:

在模板语法中,对于 { { } }和{ % % },前后的 “{ {“ 以及 “{ %” 中间是没有空格的,由于hexo渲染的问题,本篇文章的某些部分不得已在中间加空格,但切记是没有的!!!

  • 文本文件,嵌套有脚本(使用模板编程语言编写)

  • template功能:根据模块文件动态生成对应的配置文件

    • template文件必须存放于templates目录下,且命名为 .j2 结尾

    • yaml/yml 文件需和templates目录平级,目录结构如下:

      1
      2
      3
      4
      ./
      ├─ temnginx.yml
      └─ templates
      └─ nginx.conf.j2
  • Jinja2语言,使用字面量,有下面形式

    • 字符串:使用单引号或双引号
    • 数字:整数,浮点数
    • 列表:[item1, item2, …]
    • 元组:(item1, item2, …)
    • 字典:{ key1:value1, key2:value2, … }
    • 布尔型:true/false
    • 算术运算:+, -, *, /, //, %, **
    • 比较操作:==, !=, >, >=, <, <=
    • 逻辑运算:and,or,no
    • 流表达式:For,If,When

Jinja2

  • 字面量

    • 表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python 对象。如“Hello World”
    • 双引号或单引号中间的一切都是字符串。无论何时你需要在模板中使用一个 字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如42 42.23
    • 数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在 Python 里, 42 和 42.0 是不一样的
  • 算术运算

    Jinja 允许你用计算值。这在模板中很少用到,但为了完整性允许其存在

    支持下面的运算符

    • +:把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这 种方 式来衔接它们。无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 { { 1 + 1 } } 等于 2

    • -:用第一个数减去第二个数。 { { 3 - 2 } } 等于 1

    • /:对两个数做除法。返回值会是一个浮点数。 { { 1 / 2 } } 等于 { { 0.5 } }

    • //:对两个数做除法,返回整数商。 { { 20 // 7 } } 等于 2

    • %:计算整数除法的余数。 { { 11 % 7 } } 等于 4

    • *:用右边的数乘左边的操作数。 { { 2 * 2 } } 会返回 4 。也可以用于重复一个字符串多次。{ { ‘=’ * 80 } } 会打印 80 个等号的横条

    • **:取左操作数的右操作数次幂。 { { 2**3 } } 会返回 8

  • 比较操作符

    • == 比较两个对象是否相等
    • != 比较两个对象是否不等
    • > 如果左边大于右边,返回 true
    • >= 如果左边大于等于右边,返回 true
    • < 如果左边小于右边,返回 true
    • <= 如果左边小于等于右边,返回 true
  • 逻辑运算符

    对于 if 语句,在 for 过滤或 if 表达式中,它可以用于联合多个表达式

    • and

      如果左操作数和右操作数同为真,返回 true

    • or

      如果左操作数和右操作数有一个为真,返回 true

    • not

      对一个表达式取反(见下)

    • (expr)

      表达式组

  • [‘list’, ‘of’, ‘objects’]:

    一对中括号括起来的东西是一个列表。列表用于存储和迭代序列化的数据。例如 你可以容易地在 for 循环中用列表和元组创建一个链接的列表

    1
    2
    3
    4
    5
    6
    <ul>
    {% for href, caption in [('index.html', 'Index'), ('about.html', 'About'), ('downloads.html', 'Downloads')] %}
    <li>{ { caption } }</li>
    {% endfor %}
    </ul>
    (‘tuple’, ‘of’, ‘values’):
  • 元组与列表类似,只是你不能修改元组。如果元组中只有一个项,你需要以逗号 结尾它。元组通常用于表 示两个或更多元素的项。更多细节见上面的例子

    {‘dict’: ‘of’, ‘key’: ‘and’, ‘value’: ‘pairs’}:

  • Python 中的字典是一种关联键和值的结构。键必须是唯一的,并且键必须只有一个值。字典在模板中很少使用,罕用于诸如 xmlattr() 过滤器之类

    true / false:

    true 永远是 true ,而 false 始终是 false

示例

利用template 同步nginx配置文件

准备templates/nginx.conf.j2文件

vim temnginx.yml

1
2
3
4
5
- hosts: websrvs  
remote_user: root
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

ansible-playbook temnginx.yml

变更替换

  • 修改文件nginx.conf.j2 下面行为

    1
    worker_processes {{ ansible_processor_vcpus }};
  • cat temnginx2.yml

    1
    2
    3
    4
    5
    - hosts: websrvs  
    remote_user: root
    tasks:
    - name: template config to remote hosts
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

    ansible-playbook temnginx2.yml

算数运算

vim nginx.conf.j2

1
2
worker_processes { { ansible_processor_vcpus**2 } };  
worker_processes { { ansible_processor_vcpus+2 } };

for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#temnginx1.yml
---
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
tasks:
- name: config file
template: src=nginx2.conf.j2 dest=/data/nginx2.conf

#templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
#生成的结果
server {
listen 8080
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#temnginx4. yml
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
server_name: "web1.kinmfer.com"
root: "/var/www/nginx/web1/"
- listen: 8081
server_name: "web2.kinmfer.com"
root: "/var/www/nginx/web2/"
- {listen: 8082 server_ name: "web3.kinmfer.com",root:"/var/www/nginx/web3/"}
tasks:
- name: template config
template: src=nginx.conf4.j2 dest=/data/nginx4.conf

{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
server_name {{ vhost.server_name }}
root {{ vhost.root }}
}
{% endfor %}

if判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
server_name: "web2.kinmfer.com"
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web3.kinmfer.com"
root: "/var/www/nginx/web3/"
tasks:
- name: template config to
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
{% if vhost. server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %}
root {{ vhost. root }}
}
{% endfor %}