运维自动化之 ANSIBLE 详解(重点:Template、Roles 详解)

运维自动化之 ANSIBLE 详解

  • Ansible Templates
    • 1、相关概念
    • 2、Templates 功能
    • 3、Templates 示例
      • 3.1 利用 Templates 同步 nginx 配置文件
      • 3.2 利用 Templates 同步修改过后的 nginx 配置文件
    • 4、Templates 算法、条件判断、迭代的使用示例
      • 4.1 算法运算
      • 4.2 when(条件判断)
      • 4.3 with_items(迭代)
      • 4.4 with_items(迭代嵌套子变量)
      • 4.5 Playbook 中 template for if
  • Ansible Roles
    • 1、Ansible Roles 相关概念
    • 2、Ansible Roles 目录编排
      • 2.1 Roles 目录结构
      • 2.2 Roles 目录作用
      • 2.3 Roles 创建步骤
      • 2.4 Roles 目录示例
      • 2.5 Playbook 调用角色的方法
      • 2.6 完整的 Roles 架构
      • 2.7 roles playbook tags 使用
  • 推荐参考资料

Ansible Templates

1、相关概念

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

  • Jinja2语言,使用字面量,有下面形式

    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
    
  • 算术运算:+, -, *, /, //, %, **

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

  • 逻辑运算:and, or, not

  • 流表达式:For If When

2、Templates 功能

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

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

3、Templates 示例

3.1 利用 Templates 同步 nginx 配置文件

# 准备templates/nginx.conf.j2文件

vim temnginx.yml
- hosts: websrvs
  remote_user: root
  tasks:
  - name: template config to remote hosts
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf   # 在 tasks 里进行 template 引用,进行 conf 文件引用

# ansible-playbook temnginx.yml

3.2 利用 Templates 同步修改过后的 nginx 配置文件

# 当 conf 文件进行修改后,可以再运行一次 ansible-playbook 进行生效
# 修改文件nginx.conf.j2 下面行为
	worker_processes {{ ansible_processor_vcpus }};          # 修改 conf 文件,并引用 setup 变量

# cat temnginx2.yml   
- 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                             # 重新执行 ansible-playbook

4、Templates 算法、条件判断、迭代的使用示例

4.1 算法运算

vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};
worker_processes {{ ansible_processor_vcpus+2 }};

4.2 when(条件判断)

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

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

  • 示例:对 RedHat 系统的主机执行关机操作

    tasks:
    - name: "shutdown RedHat flavored systems"
      command: /sbin/shutdown -h now
      when: ansible_os_family == "RedHat"
    
  • 示例:重启主操作系统版本为 6 的主机的 nginx

    - 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
  • 示例:针对于不同的系统创建不同的配置文件

    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"
    

4.3 with_items(迭代)

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

  • 对迭代项的引用,固定变量名为”item“

  • 要在task中使用with_items给定要迭代的元素列表

  • 列表格式:

    字符串
    字典
    
  • 示例1:迭代的基本使用

    - name: add several users
      user: name={{ item }} state=present groups=wheel
      with_items:
        - testuser1
        - testuser2
    
    ### 上面语句的功能等同于下面的语句 ###
    - name: add user testuser1
      user: name=testuser1 state=present groups=wheel
    - name: add user testuser2
      user: name=testuser2 state=present groups=wheel
    
  • 示例2:将多个文件进行copy到被控端和同时安装多个软件

    ---
    
    - hosts: testsrv
      remote_user: root
      
      tasks 
      - name: Create rsyncd config 
        copy: src={{ item }} dest=/etc/{{ item }} 
        with_items: 
          - rsyncd.secrets 
          - rsyncd.conf
    
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: copy file
        copy: src={{ item }} dest=/tmp/{{ item }}
    	with_items:
    	  - file1
    	  - file2
    	  - file3
    	  - 
      - name: yum install httpd
        yum: name={{ item }} state=present
        with_items:
    	- apr
    	- apr-util
    	- httpd
    
    - hosts:websrvs
      remote_user: root
      tasks
      - name: install some packages
    	yum: name={{ item }} state=present
        with_items:
          - nginx
          - memcached
          - php-fpm
    

4.4 with_items(迭代嵌套子变量)

- 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' }

4.5 Playbook 中 template for if

{% for vhost in nginx_vhosts %} 
server { listen 
{{ vhost.listen | default('80 default_server') }}; 

{% if vhost.server_name is defined %} 
server_name {{ vhost.server_name }}; 
{% endif %} 

{% if vhost.root is defined %} 
root {{ vhost.root }}; 
{% endif %}
### temnginx.yml ###
---
- hosts: testweb
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 8080

### /templates/nginx.conf.j2 ###
{% for vhost in nginx_vhosts %}
server {
	listen {{ vhost.listen }}
}
{% endfor %}

### 生成的结果 ###
server {
	listen 8080
}
### temnginx.yml ### 
---
- hosts: mageduweb
  remote_user: root
  vars:
    nginx_vhosts:
	  - web1
	  - web2
	  - web3
  tasks:
	- name: template config
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

### templates/nginx.conf.j2 ###
{% for vhost in nginx_vhosts %}
server {
	listen {{ vhost }}
}
{% endfor %}

### 生成的结果 ###
server {
	listen web1
}
server {
	listen web2
}
server {
	listen web3
}
### temnginx.yml ### 
- hosts: mageduweb
  remote_user: root
  vars:
	nginx_vhosts:
	  - web1:
		listen: 8080
		server_name: "web1.tang.com"
		root: "/var/www/nginx/web1/"
	  - web2:
		listen: 8080
		server_name: "web2.tang.com"
		root: "/var/www/nginx/web2/"
	  - web3:
		listen: 8080
		server_name: "web3.tang.com"
		root: "/var/www/nginx/web3/“
  tasks:
	- name: template config
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

### templates/nginx.conf.j2 ###
{% for vhost in nginx_vhosts %}
server {
	listen {{ vhost.listen }}
	server_name {{ vhost.server_name }}
	root {{ vhost.root }}
}
{% endfor %}

## 生成结果 ###
server {
	listen 8080
	server_name web1.tang.com
	root /var/www/nginx/web1/
}
server {
	listen 8080
	server_name web2.tang.com
	root /var/www/nginx/web2/
}
server {
	listen 8080
	server_name web3.tang.com
	root /var/www/nginx/web3/
}
### temnginx.yml ###
- hosts: mageduweb
  remote_user: root
  vars:
	nginx_vhosts:
	  - web1:
		listen: 8080
		root: "/var/www/nginx/web1/"
	  - web2:
		listen: 8080
		server_name: "web2.magedu.com"
		root: "/var/www/nginx/web2/"
	  - web3:
		listen: 8080
		server_name: "web3.magedu.com"
		root: "/var/www/nginx/web3/"
 tasks:
	- name: template config to
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

### templates/nginx.conf.j2 ###
{% 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 %}

### 生成的结果 ###
server {
	listen 8080
	root /var/www/nginx/web1/
}
server {
	listen 8080
	server_name web2.magedu.com
	root /var/www/nginx/web2/
}
server {
	listen 8080
	server_name web3.magedu.com
	root /var/www/nginx/web3/
}

Ansible Roles

1、Ansible Roles 相关概念

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

  • 复杂场景:建议使用roles,代码复用度高

    变更指定主机或主机组
    如命名不规范维护和传承成本大
    某些功能需多个Playbook,通过includes即可实现
    
  • 角色(roles):角色集合

    roles/
    	mysql/
    	httpd/
    	nginx/
    	memcached/
    

2、Ansible Roles 目录编排

运维自动化之 ANSIBLE 详解(重点:Template、Roles 详解)_第1张图片

2.1 Roles 目录结构

  • 每个角色,以特定的层级目录结构进行组织

  • roles目录结构:

    playbook.yml
    roles/
    	project/
    	tasks/
    	files/
    	vars/
    	templates/
    	handlers/
    	default/    # 不常用
    	meta/       # 不常用
    

2.2 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 文件

2.3 Roles 创建步骤

  • 创建以roles命名的目录
  • 在roles目录中分别创建以各角色名称命名的目录,如 webservers 等
  • 在每个角色命名的目录中分别创建 files、handlers、meta、tasks、templates 和 vars 目录;用不到的目录可以创建为空目录,也可以不创建
  • 在 playbook 文件中,调用各角色

2.4 Roles 目录示例

点击查看完成的 Ansible Roles 详解示例

nginx-role.yml
roles/
└── nginx
  ├── files
  │ └── main.yml 
  ├── tasks
  │ ├── groupadd.yml
  │ ├── install.yml
  │ ├── main.yml
  │ ├── restart.yml
  │ └── useradd.yml
  └── vars
    └── main.yml

2.5 Playbook 调用角色的方法

### 调用角色方法1 :在 Playbook 里直接进行调用###
- hosts: websrvs
  remote_user: root
  roles:
	- mysql
	- memcached
	- nginx
### 调用角色方法2:传递变量给角色 ###
- hosts:
  remote_user:
  roles:
	- mysql
	- { role: nginx, username: nginx }
		### 键role用于指定角色名称 ###
		### 后续的k/v用于传递变量给角色 ###
### 调用角色方法3:还可基于条件测试实现角色调用 ###
roles:
  - { role: nginx, username: nginx, when: ansible_distribution_major_version ==7}

2.6 完整的 Roles 架构

### nginx-role.yml 顶层任务调用 yml 文件 ###
---
- hosts: testweb
  remote_user: root
  roles:
	- role: nginx
	- role: httpd    # 可执行多个role

### cat roles/nginx/tasks/main.yml ### 
---
- include: groupadd.yml
- include: useradd.yml
- include: install.yml
- include: restart.yml
- include: filecp.yml

### roles/nginx/tasks/groupadd.yml ###
---
- name: add group nginx
  user: name=nginx state=present

### cat roles/nginx/tasks/filecp.yml ### 
---
- name: file copy
  copy: src=tom.conf dest=/tmp/tom.conf

### 以下文件格式类似 ###
useradd.yml,install.yml,restart.yml

### ls roles/nginx/files/ ###
tom.conf

2.7 roles playbook tags 使用

# ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml

### nginx-role.yml ### 
---
- hosts: testweb
  remote_user: root
  roles:
	- { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6}
	- { role: httpd ,tags: [ 'httpd', 'web' ] }
	- { role: mysql ,tags: [ 'mysql', 'db' ] }
	- { role: marridb ,tags: [ 'mysql', 'db' ] }
	- { role: php }

推荐参考资料

http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
https://github.com/ansible/ansible-examples

你可能感兴趣的:(Linux学习笔记,Linux,Ansible,Roles)