ansible——template(模板)、角色

ansible——template(模板)、角色

1、template(模板)

Ansible 模板是一种强大的工具,可用于在自动化任务中以动态方式生成配置、文件和其他工件。模板使用 Jinja2 模板语言,这是一种功能强大的模板语言,可用于创建复杂的模板。

Jinja2 模板语言:使用字面量,有下面形式。

  • 字符串:使用单引号或者双引号

  • 数字:整数、浮点数

  • 列表:[item1、item2、......]

  • 元组:[item1、item2、......]

  • 字典:[key1:value1,key2:value2,......]

  • 布尔型:true/false

算数运算:+ ,-, *, /,/ /,%,**

比较操作:==, !=, >, >=, <, <=

逻辑运算:and、or、not

流表达式:If     For     When

1、template使用

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

template文件必须存放于templates目录下,且命名为 .j2 结尾 yaml/yml 文件需和templates目录平级,目录结构如下: ./ ├── temnginx.yml └── templates └── nginx.conf.j2

示例1
[root@node2 templates]# vim testtemp.yml
---
- hosts: 10.0.0.1
  remote_user: root
​
  tasks:
    - name: install package
      yum: nginx
    - name: copy template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
    - name: service start
      service: name=nginx state=started enabled=yes
[root@node2 templates]# ansible-playbook -C testtemp.yml
[root@node2 templates]# ansible 10.0.0.1 -m shell -a 'rpm -q nginx' 
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.  If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
10.0.0.1 | CHANGED | rc=0 >>
nginx-1.20.1-10.el7.x86_64
示例2:

给nginx的端口修改了一下——引用了/etc/ansible/hosts中的变量

---
- hosts: 10.0.0.1
  remote_user: root
  tasks:
    - name: install package
      yum: name=nginx
    - name: copy template
      template: src=/root/ansible/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
    - name: start service
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart service
      service: name=nginx state=restarted enabled=yes
      
[root@node2 templates]# ansible 10.0.0.1 -m shell -a 'ss -ntl | grep 82'
10.0.0.1 | CHANGED | rc=0 >>
LISTEN     0      128          *:82                       *:*                  
LISTEN     0      128       [::]:82                    [::]:*  

变量的优先级:命令行》yml文件中定义的变量》/etc/ansible/hosts(主机清单)中定义的变量——单一变量大于公共变量

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

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

    示例:

tasks:
name: "shutdown RedHat flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "RedHat"  当系统属于红帽系列,执行command模块 

补充:过滤系统版本号

[root@node2 ~]# ansible all -m setup -a 'filter=ansible_os_family' 
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
    }, 
    "changed": false
}
10.0.0.8 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
    }, 
    "changed": false
}
10.0.0.1 | SUCCESS => {
    "ansible_facts": {
        "ansible_os_family": "RedHat", 
    }, 
    "changed": false
}
示例1:when条件判断
示例:
- hosts: 10.0.0.1
  remote_user: root
  tasks:
  - name: install package
    yum: name=nginx
  - name: copy conf file to centos7
    template: src=templates/nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == "7"
  - name: copy conf file to centos6
    template: src=templates/nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == "6"
  - name: start service
    service: name=nginx state=started enabled=yes
    
# 复制相应的CentOS6的nginx配置文件到本主机上,然后进行操作
3、迭代:with_items

在Ansible中,迭代是一种常用的功能,用于在任务或模块中重复执行相同的操作。

迭代:当有需要重复性执行的任务时,可以使用迭代机制
    > 对迭代项的引用,固定变量名为"item"
    > 要在task中使用with_items给定要迭代的元素列表
    > 列表格式:
         字符串
         字典
示例1:
[root@node2 ansible]# vim testitem.yml
---
- hosts: 10.0.0.1
  remote_user: root
  tasks:
    - name: create some files
      file: name=/data/{{ item }} state=touch
      with_items:
        - file1
        - file2
        - file3
方法2:
---
- hosts: 10.0.0.1
  remote_user: root
  tasks:
    - name: create file file1
      file: name=file1 state=touch
    - name: create file file1
      file: name=file2 state=touch
    - name: create file file1
      file: name=file3 state=touch
[root@node2 ansible]# ansible-playbook -C testitem.yml 
迭代套子变量:
- hosts:10.0.0.1
  remote_user: root
  
  tasks:
    - name: add some groups
      group: name={{ item }} state=present
      with_items:
        - g1
        - g2
        - g3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'u1', group: 'g1' }
        - { name: 'u2', group: 'g2' }
        - { name: 'u3', group: 'g3' }
[root@node2 ansible]# ansible-playbook -C testitem.yml 
[root@node2 ansible]# ansible-playbook testitem.yml 
[root@node2 ansible]# ansible 10.0.0.1 -m shell -a 'getent group'
g1:x:1002:
g2:x:1003:
g3:x:1004:
[root@node2 ansible]# ansible 10.0.0.1 -m shell -a 'getent passwd'
u1:x:1002:1002::/home/u1:/bin/bash
u2:x:1003:1003::/home/u2:/bin/bash
u3:x:1004:1004::/home/u3:/bin/bash
template中的 for if when循环

template中的 for

[root@node2 ansible]# vim testfor.yml 
---
- hosts: 10.0.0.1
  remote_user: root
  vars:
    ports:
      - 80
      - 81
      - 82
  tasks:
    - name: copy conf
      template: src=templates/for.conf.j2  dest=/data/for.conf
方法2:
---
- hosts: 10.0.0.1
  remote_user: root
  vars:
    ports:
      - listen_port: 80
      - listen_port: 81
      - listen_port: 82
​
  tasks:
    - name: copy conf
      template: src=templates/for.conf.j2  dest=/data/for.conf  
[root@node2 templates]# vim for.conf.j2
{% for port in ports %}
server{
        listen {{port}}
{% endfor %}
[root@node2 ansible]# ansible-playbook testfor.yml    # 此时已经将端口内容复制到目标主机
[root@node2 ansible]# ansible 10.0.0.1 -m shell -a 'rm -f /data/for.conf'

示例2:

[root@node2 templates]# vim for.conf.j2
{% for p in ports %}
server{
        listen {{ p.port }}
        servername {{ p.name }}
        documentroot {{ p.rootdir }}
{% endfor %}
​
[root@node2 ansible]# vim testfor.yml 
---
- hosts: 10.0.0.1
  remote_user: root
  vars:
    ports:
      - web1:
        port: 80
        name: www.haha1.com
        rootdir: /data/website1
      - web2:
        port: 81
        name: www.haha2.com
        rootdir: /data/website2
      - web3:
        port: 82
        name: www.haha3.com
        rootdir: /data/website3
​
  tasks:
    - name: copy conf
      template: src=templates/for.conf.j2  dest=/data/for.conf
[root@node2 ansible]# ansible-playbook testfor.yml
# 查看另一台主机复制的内容
[root@node1 ~]# cat /data/for.conf 
server{
        listen 80
        servername www.haha1.com
        documentroot /data/website1
server{
        listen 81
        servername www.haha2.com
        documentroot /data/website2
server{
        listen 82
        servername www.haha3.com
        documentroot /data/website3

template中的 for if

[root@node2 ansible]# vim testfor.yml
---
- hosts: 10.0.0.1
  remote_user: root
  vars:
    ports:
      - web1:
        port: 80
        #name: www.haha1.com
        rootdir: /data/website1
      - web2:
        port: 81
        name: www.haha2.com
        rootdir: /data/website2
      - web3:
        port: 82
        #name: www.haha3.com
        rootdir: /data/website3
​
  tasks:
    - name: copy conf
      template: src=templates/for.conf.j2  dest=/data/for.conf
[root@node1 ~]# cat /data/for.conf 
server{
        listen 80
        documentroot /data/website1
server{
        listen 81
        servername www.haha2.com
        documentroot /data/website2
server{
        listen 82
        documentroot /data/website3

2、roles

roles概念:

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

复杂场景:建议使用roles,代码复用度高 变更指定主机或主机组 如命名不规范维护和传承成本大 某些功能需多个Playbook,通过includes即可实现

角色(roles):角色集合 roles/ mysql/ httpd/ nginx/ memcached/ 所有角色都可以互相调用

role目录结构

playbook.yml 调用角色应该与roles角色的目录平级

├── nginx.role.yml
├── roles
│   └── nginx
│       ├── tasks
│       │   ├── group.yml
│       │   ├── main.yml
│       │   ├── restart.yml
│       │   ├── start.yml
│       │   ├── template.yml
│       │   ├── user.yml
│       │   └── yum.yml
│       └── templates
│           └── nginx.conf.j2

roles各目录作用:
/roles/project/ :项目名称,有以下子目录
    files/ :存放由copy或script模块等调用的文件
    templates/:template模块查找所需要模板文件的目录
    tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;
            其它的文件需要在此文件中通过include进行包含
    handlers/:至少应该包含一个名为main.yml的文件;
               其它的文件需要在此文件中通过include进行包含
    vars/:定义变量,至少应该包含一个名为main.yml的文件;
           其它的文件需要在此文件中通过include进行包含
    meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,
           其它文件需在此文件中通过include进行包含
    default/:设定默认变量时使用此目录中的main.yml文件
    
roles/appname 目录结构
    tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;
               此文件可以使用include包含其它的位于此目录中的task文件
    files目录:存放由copy或script等模块调用的文件;
    templates目录:template模块会自动在此目录中寻找Jinja2模板文件
    handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;
                  在handler中使用include包含的其它的handler文件也应该位于此目录中;
    vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
    meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;
              ansible1.3及其以后的版本才支持;
    default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件
​
roles/example_role/files/             所有文件,都将可存放在这里
roles/example_role/templates/         所有模板都存放在这里
roles/example_role/tasks/main.yml:   主函数,包括在其中的所有任务将被执行
roles/example_role/handlers/main.yml:所有包括其中的 handlers 将被执行
roles/example_role/vars/main.yml:    所有包括在其中的变量将在roles中生效
roles/example_role/meta/main.yml:    roles所有依赖将被正常登入

示例1:

[root@node2 roles]# tree
├── nginx.role.yml
├── roles
│   └── nginx
│       ├── tasks
│       │   ├── group.yml
│       │   ├── main.yml
│       │   ├── restart.yml
│       │   ├── start.yml
│       │   ├── template.yml
│       │   ├── user.yml
│       │   └── yum.yml
│       └── templates
│           └── nginx.conf.j2
[root@node2 ansible]# cd roles/
[root@node2 roles]# ll
drwxr-xr-x. 4 root root 4096 Jan  9 16:40 nginx
-rwxr-xr-x. 1 root root   70 Jan  9 17:04 nginx.role.yml
[root@node2 nginx]# ll
total 8
drwxr-xr-x. 2 root root 4096 Jan  9 17:02 tasks
drwxr-xr-x. 2 root root 4096 Jan  9 16:59 templates
[root@node2 tasks]# ll
total 28
-rwxr-xr-x. 1 root root  48 Jan  9 16:56 group.yml
- name: create group
  group: name=nginx gid=82
-rwxr-xr-x. 1 root root 105 Jan  9 17:02 main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml
-rwxr-xr-x. 1 root root  74 Jan  9 16:56 restart.yml
- name: service restart
  service: name=nginx state=restarted enabled=yes
-rwxr-xr-x. 1 root root  70 Jan  9 16:56 start.yml
- name: service start
  service: name=nginx state=started enabled=yes
-rwxr-xr-x. 1 root root 111 Jan  9 16:49 template.yml
- name: copy conf
  template: src=/root/ansible/roles/nginx/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
-rwxr-xr-x. 1 root root  89 Jan  9 16:56 user.yml
- name: create user
  user: name=nginx uid=82 group=nginx system=yes shell=/sbin/nologin
-rwxr-xr-x. 1 root root  43 Jan  9 16:46 yum.yml
- name: install package
  yum: name=nginx 
[root@node2 nginx]# cd templates/
[root@node2 templates]# ll
total 4
-rw-r--r--. 1 root root 2364 Jan  9 16:59 nginx.conf.j2
示例2:
# 再创建一个角色
├── httpd.role.yml
├── nginx.role.yml
├── roles
│   ├── httpd
│   │   ├── files
│   │   │   └── http.conf
│   │   └── tasks
│   │       ├── copyfile.yml
│   │       ├── main.yml
│   │       └── user.yml
│   └── nginx
│       ├── tasks
│       │   ├── group.yml
│       │   ├── main.yml
│       │   ├── restart.yml
│       │   ├── start.yml
│       │   ├── template.yml
│       │   ├── user.yml
│       │   └── yum.yml
│       └── templates
│           └── nginx.conf.j2
[root@node2 ansible]# vim httpd.role.yml
---
- hosts: 10.0.0.1
  remote_user: root
  roles:
    - httpd
[root@node2 tasks]# vim copyfile.yml
- name: copy files
  file: src=/root/ansible/roles/httpd/files/http.conf dest=/data/ owner=apache
[root@node2 tasks]# vim main.yml
- include: user.yml
- include: copyfile.yml
[root@node2 tasks]# vim user.yml
- name: create user
  user: name=apache system=yes shell=/sbin/nologin
[root@node2 ansible]# ansible-playbook httpd.role.yml 
​
​
# 同时在一台主机上调用两个不同角色
[root@node2 ansible]# vim some.role.yml
---
- hosts: 10.0.0.1
  remote_user: root
  roles:
    - nginx
    - httpd
# 在某个角色中想调用另一个角色的yml文件(本例是在nginx角色中调用httpd的copyfile.yml文件)
[root@node2 tasks]# vim user.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml
- include: roles/httpd/tasks/copyfile.yml
[root@node2 ansible]# ansible-playbook nginx.role.yml 
TASK [nginx : copy files] ***************************************************************************************
changed: [10.0.0.1]
# 针对不同角色,可以给每个角色添加标签
[root@node2 ansible]# vim some.role.yml
---
- hosts: 10.0.0.1
  remote_user: root
  roles:
    - { role: nginx,tags: ['web','nginx'] }
    - { role: httpd,tags: ['web','httpd'] ,when ansible_distribution_major_version="7"}
注释:标签内容为单个可以使用""
[root@node2 ansible]# ansible-playbook -C -t 'web','nginx' some.role.yml
示例3:
├── app.role.yml
---
- hosts: 10.0.0.1
  remote_user: root
  roles:
    - app
├── roles
│   ├── app
│   │   ├── files
│   │   │   └── vhosts.conf
│   │   ├── handlers
│   │   │   └── main.yml
- name: service restart
  service: name=httpd state=restarted enabled=yes
│   │   ├── tasks
│   │   │   ├── copyfile.yml
│   │   │   ├── group.yml
│   │   │   ├── main.yml
│   │   │   ├── start.yml
│   │   │   ├── templ.yml
│   │   │   ├── user.yml
│   │   │   └── yum.yml
│   │   ├── templates
│   │   │   └── http.conf.j2
│   │   └── vars
│   │       └── main.yml
username: app
groupname: app
[root@node2 ansible]# ansible-playbook -C app.role.yml

补充:

[root@k8s-node2 ansible]# ansible all -m setup -a 'filter="*memtotal*"'       # 过滤出内存的大小
10.0.0.1 | SUCCESS => {
    "ansible_facts": {
        "ansible_memtotal_mb": 2048, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

下载ansible的角色模板的网址Ansible 星系

  • 16
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值