一篇精通Ansible之playbook

news2024/11/23 15:18:23

华子目录

  • 前言
  • `playbook`概念
    • `playbook`结构理解
    • `playbook`核心元素
    • `playbook`特点与优势
  • `playbook`基本语法
  • `ansible-playbook`命令
  • ansible总结
  • 查看主机清单
  • ansible配置文件
  • 单个play
    • 语法检测
    • 运行
  • 多个play
  • 查看模块doc
  • 变量
    • 事实变量
    • 导入变量文件
    • 字典变量
  • 机密数据管理
    • 在`playbook`中导入变量文件
      • 导入加密变量文件和普通文件
  • register
  • 流程控制
    • ansible中的循环机制`loop`
    • when
    • `notify`与`handlers`
    • ignore_errors
    • block,rescue,always
  • changed_when
  • 包含文件与导入文件
  • 角色
    • 列出角色
    • 运行角色
    • 安装collection
    • 列出colection
  • `pre_tasks` `post_tasks`
  • 总结

前言

  • Ansible中,playbooks剧本)是用来定义一系列task任务的文件,可以实现自动化部署、配置和管理服务器等操作
  • 本文主要介绍playbook剧本的组成以及编写

playbook概念

  • playbook是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活
  • playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础
  • playbook实质就是一个文件,有着特定的组织格式,它采用的语法格式是yamlYet Another Markup Language
  • playbook是由一个或多个play组成的列表

playbook结构理解

  • 集合:多个模块集合体

  • 在这里插入图片描述

  • 任务清单playbook

    • 一个playbook中可以有多个playplaybookplay的集合体)
    • 一个play中可以有多个任务task(每个play可以单独指定主机范围)(task只能在其所属play指定的主机上执行)(每个task当中可以存在多个ansible操作模块
    • 在这里插入图片描述
  • 除了playbook之外,还有playbook需要的模板,文件,变量文件等等不能全都放在playbook中,否则会使得playbook变得臃肿。我们就需要单独进行存放

  • 最后,我们会把playbookplaybook需要的模板,文件,变量文件等等进行打包。形成一个角色role

  • 在这里插入图片描述

playbook核心元素

在这里插入图片描述

  • hosts主机列表远程主机列表
  • task任务集:通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
  • variables变量:用来存储数据,可以在playbook中被引用。这些变量可以是全局的,也可以是针对特定主机或主机组的。使用变量可以使playbook更加灵活和可重用
  • templates模板:一种用来生成配置文件或者其他文本文件机制。在Ansible中,你可以使用Jinja2模板引擎来创建模板文件。这些模板文件中可以包含变量、条件语句、循环等,使得你可以根据不同的情况生成不同的文本内容
  • handlers处理器:一种特殊类型任务,它们仅在特定条件下触发。通常用于在一组任务执行完成后执行诸如修改配置文件重启服务之类的操作。当服务配置文件changed被修改需要重启服务进行重新加载时,触发执行的操作
    • handlersnotity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • roles角色:用来组织playbooks中任务的结构化方式。一个role包含了一组相关的任务、变量、handlers、文件等内容,可以使得playbooks更加模块化、可重用和易于维护
  • tags标签,指定某条任务执行,用于选择运行playbook中的部分代码
  • remote_user:在远程主机哪个用户身份执行;

playbook特点与优势

  • 声明式:用户只需描述期望的系统状态,而非具体的操作步骤,Ansible 负责确定如何达到这一状态
  • 幂等性Playbook 设计为可重复执行,即使在系统已处于预期状态时,再次运行也不会产生副作用
  • 可读性强yaml 格式和简洁的结构使得Playbook易于编写和维护
  • 模块丰富Ansible 提供了大量的模块,覆盖了从系统配置到云资源管理的广泛需求
  • 跨平台:支持多种操作系统环境,适配不同的自动化需求

playbook基本语法

playbook使用yaml语法格式,后缀可以是yaml,也可以是yml

  • 第一种写法:
[root@server ~]# vim test.yaml
---         #yaml文件以---开头,以表明这是一个yaml文件,可省略
- name: first-play     #定义一个play的名称,可省略
  hosts: all          #  -表示一个块序列的节点,注意:横杠后面有空格,可以写主机名,主机组名,多个主机名使用逗号隔开
  remote_user: root    #指定在进行远程操作时使用root用户进行操作
  become: true     #是否提权
  become_user: root    #提权的用户为root
  tasks:        #使用tasks关键字指明要进行操作的任务列表,之后的行都属于tasks键值对中的值
  - name: PING!!!    #每个任务都以-开头,每个任务都有自己的名字(名字自定义),任务名使用name关键字进行指定
    ping:        #ansible中的ping模块
  - name: make directory!!!     #第二个任务名(任务名自定义)
    file:       #ansible中的file模块
       path: /root/data     
       state: directory

在这里插入图片描述

  • 注意:键值对之间必须要有一个空格

  • 第二种写法:(推荐写法

[root@server ~]# vim test1.yaml
---                #  ---表示文档开始
- name: first-play     #定义一个play的名称,可省略
  hosts: node1.example.com              #  -表示一个块序列的节点,注意:横杠后面有空格,可以写主机名,主机组名,多个主机名使用逗号隔开
  remote_user: root              #指定在进行远程操作时使用root用户进行操作
  become: true     #是否提权
  become_user: root    #提权的用户为root
  vars:             #表示下面是定义的变量
       filename: file1          #变量的形式,key: value
  vars_files:   #导入变量文件,相当于include。对于导入的变量文件中的变量,直接使用即可
    - /home/student/data-secret/secret.yml  #加密变量文件
    - ./user.yml        #普通变量文件
  tasks:                 #使用tasks关键字指明要进行操作的任务列表,之后的行都属于tasks键值对中的值
  - name: touch file!!!          #第一个任务名(任务名自定义)
    file: path=/root/{{ filename }} state=touch    #file为ansible的模块,file:后接模块参数(使用=号)

在这里插入图片描述

  • 使用 {{ key }} 引用变量的
  • name下面接模块名

ansible-playbook命令

[root@server ~]# ansible-playbook   [options]   playbook.yml
参数说明
-i指定inventory文件的路径,用于指定要管理的主机清单
-k用来交互输入ssh密码
-K用来交互输入sudo(普通用户)密码
-u指定用户
-l指定要运行剧本的主机或主机组
-e命令行中指定变量,当与剧本中的变量名重复时,会覆盖剧本中变量
-t指定要运行的标签,只运行带有指定标签的任务
--syntax-check检查yaml文件的语法是否正确
--step执行tasks中的任务,需要手动确认是否往下执行
--list-tasks列出剧本中的所有任务
--list-hosts检查生效的主机
--start-at-task指定从某个task开始运行,如--start-at-task='install httpd'
-C测试运行playbook,但不显示测试结果
[root@server ~]# ansible-playbook playbook.yaml --syntax-check   #检查yaml文件的语法是否正确

[root@server ~]# ansible-playbook playbook.yaml --list-task    #列出task任务

[root@server ~]# ansible-playbook playbook.yaml --list-hosts     #检测生效的主机

[root@server ~]# ansible-playbook -C playbook.yaml   #-C测试运行(没有运行结果)
  • 执行 playbook 剧本
[root@server ~]# ansible-playbook playbook.yaml

ansible总结

  • ansible中,ansible.cfghosts文件是ansible的默认配置文件,如果在当前目录运行ansible指令的时候,当前目录下有ansible.cfghosts文件,就会加载当前目录的。如果当前目录下没有ansible.cfghosts文件,ansible就会加载/etc/ansible/ansible.cfg/etc/ansible/hosts文件

查看主机清单

[student@workstation ~]$ ansible-navigator inventory -i 清单文件目录 -m stdout --graph

[student@workstation ~]$ ansible-inventory --graph

ansible配置文件

  • 自动生成配置文件
[student@workstation ~]$ ansible-config init --disabled > ansible.cfg  #在当前目录下生成ansible配置文件
  • 手动编辑
[student@workstation ~]$ vim ansible.cfg
[defaults]
inventory=inventory   #定义主机清单
collections_path=mycollections 
roles_path=roles
remote_user=root   #在受管主机上登录的用户名称
ask_pass=false   #是否询问ssh密码
vault_password_file=secret.txt  #存放密码的文件

[privilege_escalation]    #权限升级
become=true       
become_method=sudo     #提升权限的方法
become_ask_pass=false  #是否为become_method提示输入密码
become_user=root     #切换到的用户

单个play

  • 每一个play管理一部分主机

  • 一个play管理一部分主机

在这里插入图片描述

语法检测

[student@workstation playbook-basic]$ ansible-navigator run -m stdout site.yml --syntax-check #语法检测

运行

[student@workstation playbook-basic]$ ansible-navigator run -m stdout site.yml #运行ansible脚本,对于幂指型重复运行不会有影响。但是对command,shell,raw这样的非幂指型有影响

多个play

[student@workstation playbook-multi]$ vim intranet.yml
---
- name: enable intranet services
  hosts: servera
  become: true  #提权
  become_user: root  #提权为root用户
  tasks:
    - name: latest version of httpd and firewalld installed
      ansible.builtin.dnf:
        name:
          - httpd     #使用列表的形式,安装多个软件包
          - firewalld
        state: latest

    - name: test html page is installed
      ansible.builtin.copy:
        content: "welcome to the example.com intranet\n"  #复制的内容,\n表示换行
        dest: /var/www/html/index.html   #复制到的位置
        
    - name: firewalld started
      ansible.builtin.service:   #开启firewalld
        name: firewalld
        state: started
        enabled: true

    - name: firewall permit httpd
      ansible.posix.firewalld:
        service: http   #服务名
        permanent: true  #设置为永久性
        state: enabled  #放行http
        immediate: yes  #不用重启,立即生效
        
    - name: httpd started
      ansible.builtin.service:
        name: httpd   #服务名
        state: started  #设置为开启
        enabled: true  #开机自启动

- name: test intranet web server
  hosts: localhost   #本机
  become: false   #是否提升权限
  tasks:
    - name: connect to intranet web server
      ansible.builtin.uri:
        url: http://servera.lab.example.com  #访问的网址
        return_content: yes  #是否返回内容
        status_code: 200  #判断是否访问成功
[student@workstation playbook-review]$ vim internet.yml
---
- name: enable internet web service
  hosts: serverb.lab.example.com
  become: true
  tasks:
    - name: firewalld httpd mariadb php php-mysqlnd installed   #安装多个软件包
      ansible.builtin.dnf:
        name:
          - firewalld
          - httpd
          - mariadb-server
          - php
          - php-mysqlnd
        state: latest
        
    - name: firewalld enabled  #启动防火墙
      ansible.builtin.service:
        name: firewalld
        state: started
        enabled: true

    - name: permit httpd   #放行http服务
      ansible.posix.firewalld:
        service: http
        state: enabled
        permanent: true
        immediate: yes

    - name: httpd enabled   #httpd开机自启动
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: true

    - name: mariadb enabled  #mariadb开机自启动
      ansible.builtin.service:
        name: mariadb
        state: started
        enabled: true

    - name: copy index.php   #copy文件并设置文件权限
      ansible.builtin.copy:
        src: index.php
        dest: /var/www/html/index.php
        mode: 0644

- name: test web server
  hosts: workstation
  become: false
  tasks:
    - name: connect to server
      ansible.builtin.uri:
        url: http://serverb.lab.example.com
        status_code: 200

查看模块doc

[student@workstation playbook-multi]$ ansible-doc --list | grep uri
debug                                          Print statements during exec...
uri                                            Interacts with webservices
[student@workstation playbook-multi]$ ansible-doc -l | grep uri
debug                                          Print statements during exec...
uri                                            Interacts with webservices
[student@workstation playbook-multi]$ ansible-doc uri   #查看uri模块的详细信息

变量

在这里插入图片描述

  • playbook中定义变量
[student@workstation data-variables]$ vim playbook.yml
---
- name: deploy and start apache httpd service
  hosts: webserver
  vars:       #在yml文件中定义变量
    web_pkg: httpd
    firewall_pkg: firewalld
    web_service: httpd
    firewall_service: firewalld
    python_pkg: python3-PyMySQL
    rule: http
  tasks:
    - name: install packages
      ansible.builtin.dnf:  #安装软件包
        name:
          - "{{ web_pkg }}"   #引用变量
          - "{{ firewall_pkg }}"
          - "{{ python_pkg }}"
        state: latest

    - name: firewalld enabled #启动firewalld
      ansible.builtin.service:
        name: "{{ firewall_service }}"
        state: started
        enabled: true

    - name: firewalld rule to http #放行防火墙规则
      ansible.posix.firewalld:
        service: "{{ rule }}"
        state: enabled
        permanent: true
        immediate: yes

    - name: copy file to http #创建网页文件
      ansible.builtin.copy:
        content: "Example web content\n"
        dest: /var/www/html/index.html

    - name: httpd enabled  #启动httpd服务
      ansible.builtin.service:
        name: "{{ web_service }}"
        state: started
        enabled: true

- name: verify http service  #http服务检测是否正常
  hosts: workstation
  become: false
  tasks:
    - name: look http server
      ansible.builtin.uri:
        url: http://servera.lab.example.com
        status_code: 200  #检测是否为200,不是200会报错

事实变量

  • 事实变量:收集到的远程主机的主机名,ip地址等等

  • setup模块自动在playbook执行时被触发,并且收集到的信息默认就被存储在Ansible变量中(ansible_facts变量)

[student@workstation data-variables]$ ansible all -m setup   #会在当前目录下寻找清单文件中的所有主机的事实
  • 如何引用事实变量

在这里插入图片描述

[student@workstation data-facts]$ vim dispaly_facts.yml
---
- name: display ansible facts
  hosts: webserver
  tasks:
    - name: display all facts
      ansible.builtin.debug:
        msg: "{{ ansible_facts['fqdn'] }}"

在这里插入图片描述

导入变量文件

  • 使用vars_files参数
[student@workstation data-secret]$ vim create_users.yml
---
- name: create user
  hosts: devservers
  become: true
  remote_user: devops
  vars_files:   #该加密变量文件密码是redhat (文件变量列表可以有多个,也可以有一个)
    - /home/student/data-secret/secret.yml  #加密变量文件
    - ./user.yml        #普通变量文件
  tasks:
    - name: creating user from secret.yml
      ansible.builtin.user:
        name: "{{ username }}"  #直接引用变量即可
        password: "{{ pwhash }}"
        
    - name: create user
      ansible.builtin.user: 
        name: "{{ user }}"  #直接引用变量即可
        password: "{{ passwd }}"

字典变量

  • 变量值也可以时字典类型
---
- name: Deploy /etc/hosts file  # Playbook 名称
  hosts: all  # 目标主机组,指定该 Playbook 应用到所有主机
  vars:
    hosts:  # 定义 hosts 变量,包括主机名称和 IP 地址的列表
      - { name: 'host1', ip: '192.168.1.2' }  # 定义主机1的信息
      - { name: 'host2', ip: '192.168.1.3' }  # 定义主机2的信息
      - { name: 'host3', ip: '192.168.1.4' }  # 定义主机3的信息
  tasks:
    - name: Deploy /etc/hosts from template  # 任务名称
      template:
        src: templates/hosts.j2  # 指定模板文件路径(相对于 templates 目录)
        dest: /etc/hosts  # 指定模板文件复制到远程主机的目标路径

机密数据管理

  • 第一种方式创建机密文件,密码可能容易忘记
[student@workstation ~]$ ansible-vault create secret.yml  #创建机密文件,需要设置密码
hello world


[student@workstation ~]$ cat secret.yml   #发现内容已加密
  • 第二种方式:先创建密码文件,再创建机密文件,机密文件的密码在密码文件中
[student@workstation ~]$ echo huazi > password.txt

[student@workstation ~]$ ansible-vault create --vault-password-file=password.txt secret.yml
hello world
  • 查看机密文件内容
[student@workstation ~]$ ansible-vault view secret.yml
Vault password:            #这里需要输入密码
hello world
  • 查看机密文件内容时,指定密码文件
[student@workstation ~]$ ansible-vault view --vault-password-file=password.txt secret.yml
hello world
  • 编辑机密文件(相当于vim)(不能使用vim直接编辑,因为使用vim进入后是密文)
[student@workstation ~]$ ansible-vault edit secret.yml
Vault password:   #这里需要输入密码才能进入编辑模式
#指定密码文件,进入机密文件中
[student@workstation ~]$ ansible-vault edit --vault-password-file=password.txt secret.yml
  • 解密机密文件
[student@workstation ~]$ ansible-vault decrypt --vault-password-file=password.txt secret.yml
Decryption successful      #解密成功
[student@workstation ~]$ cat secret.yml  #可以正常查看内容
hello world
  • 将普通文件加密为机密文件
[student@workstation ~]$ ansible-vault encrypt --vault-password-file=password.txt secret.yml
Encryption successful   #加密成功
[student@workstation ~]$ cat secret.yml  #发现为加密内容
  • 重置密码
[student@workstation ~]$ ansible-vault rekey secret.yml
Vault password:    #huazi   原密码
New Vault password:  #redhat  新密码
Confirm New Vault password:   #redhat  新密码
Rekey successful
[student@workstation ~]$ ansible-vault view secret.yml
Vault password:   #redhat  新密码
hello world

playbook中导入变量文件

  • 使用vars_files

导入加密变量文件和普通文件

  • 导入文件后,文件中的变量直接引用即可
[student@workstation data-secret]$ ansible-vault view --vault-password-file=password.txt secr   et.yml     #查看加密文件内容
username: ansibleuser1
pwhash: $6$jfnHouVKUTFMM1pm$39OVTp0ZL8FX.QbD1GoUCP12pNrTC2XzX9Ec0UhzwAM76A.B.Yrk8S.8xiSSnAc.>



[student@workstation data-secret]$ cat user.yml #查看普通文件内容
user: huazi
passwd: "{{ '123456' | password_hash('sha512') }}"  #密码要经过加密才能使用
[student@workstation data-secret]$ vim create_users.yml
---
- name: create user
  hosts: devservers
  become: true
  remote_user: devops
  vars_files:   #该加密变量文件密码是redhat (文件变量列表可以有多个,也可以有一个)
    - /home/student/data-secret/secret.yml  #加密变量文件
    - ./user.yml        #普通变量文件
  tasks:
    - name: creating user from secret.yml
      ansible.builtin.user:
        name: "{{ username }}"  #直接引用变量即可
        password: "{{ pwhash }}"
        
    - name: create user
      ansible.builtin.user: 
        name: "{{ user }}"  #直接引用变量即可
        password: "{{ passwd }}"
  • 由于在create_users.yml中导入了机密文件,所以在执行create_users.yml文件时,需要--vault-password-file指定密码文件
[student@workstation data-secret]$ echo redhat > password.txt

[student@workstation data-secret]$ ansible-navigator run -m stdout create_users.yml --vault-password-file=password.txt

register

  • register定义的变量会接受模块运行后的所有结果,包括状态,屏幕回显等等。与模块同级,放在模块后面
[student@workstation data-facts]$ vim check_httpd.yml
---
- name: check server
  hosts: webserver
  tasks:
    - name: check
      ansible.builtin.command: "systemctl is-active httpd"
      register: result             #register声明变量
    - name: dispaly
      ansible.builtin.debug:
        var: result.stdout    #使用  变量名.stdout  打印systemctl is-active httpd的屏幕回显

流程控制

ansible中的循环机制loop

Ansible 中的循环机制主要通过几个关键元素实现

  • 常用itemloop关键字,loop放在模块的最后面,与模块同级
[student@workstation control-flow]$ vim play.yml
---
- name: print msg
  hosts: servera.lab.example.com
  vars:
    list:    #定义变量列表,list为列表名,one two three为列表中的值
      - one
      - two
      - three

  tasks:
    - name: print
      ansible.builtin.debug:
        var: "item"  
      loop: "{{ list }}"
[student@workstation control-flow]$ ansible-navigator run -m stdout play.yml

PLAY [print msg] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]

TASK [print] *******************************************************************
ok: [servera.lab.example.com] => (item=one) => {
    "ansible_loop_var": "item",
    "item": "one"
}
ok: [servera.lab.example.com] => (item=two) => {
    "ansible_loop_var": "item",
    "item": "two"
}
ok: [servera.lab.example.com] => (item=three) => {
    "ansible_loop_var": "item",
    "item": "three"
}

PLAY RECAP *********************************************************************
servera.lab.example.com    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

案例:使用loop安装多个软件包

[student@workstation control-flow]$ vim playbook.yml
---
- name: mariadb server is running
  hosts: database_dev
  vars:
    mariadb_packages:
      - mariadb-server
      - python3-PyMySQL

  tasks:
    - name: install
      ansible.builtin.dnf:
        name: "{{ item }}"
        state: present
      loop: "{{ mariadb_packages }}"

when

  • Ansible 中,提供的唯一一个通用的条件判断是 when 指令,当 when 指令的返回值为 true 时,则该任务执行,否则不执行该任务
  • when指令中的变量名不需要手动加上 {{ }}
[student@workstation control-flow]$ vim playbook.yml
---
- name: mariadb server is running
  hosts: servera.lab.example.com
  vars:
    mariadb_packages:
      - mariadb-server
      - python3-PyMySQL

  tasks:
    - name: install
      ansible.builtin.dnf:
        name: "{{ item }}"
        state: present
      loop: "{{ mariadb_packages }}"
      when: ansible_facts['fqdn'] == "huazi" #当不满足这个条件时,返回false,不执行

    - name: start service
      ansible.builtin.service:
        name: mariadb
        state: started
        enabled: true
[student@workstation control-flow]$ ansible-navigator run -m stdout playbook.yml

PLAY [mariadb server is running] ***********************************************

TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]

TASK [install] *****************************************************************
skipping: [servera.lab.example.com] => (item=mariadb-server)  #skipping表示条件不满足,跳过了
skipping: [servera.lab.example.com] => (item=python3-PyMySQL)

TASK [start service] ***********************************************************
ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************
servera.lab.example.com    : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

notifyhandlers

  • notify下的名字必须和handlers中的name的名字相同。

  • handlers会等上面任务执行完成后再执行

  • notify放在模块的最后,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。

  • 在系统中,我们修改了服务器的配置文件,这时候就需要重启服务,就可以使用到handlers。配合notify使用

  • handlers等价于playbook中的tasks的位置

[student@workstation control-flow]$ vim plalbook.yml
---
- name: restart http service
  hosts: servera.lab.example.com
  tasks:
    - name: httpd installed  #安装httpd
      ansible.builtin.dnf:
        name: httpd
        state: present
    - name: httpd started  #启动httpd
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: true
    - name: reset index.html   #修改网页内容
      ansible.builtin.copy:
        content: "huazi\n"
        dest: /var/www/html/index.html
      notify: restart httpd

  handlers:
    - name: restart httpd   #重启httpd
      ansible.builtin.service:
        name: httpd
        state: restarted

ignore_errors

ignore_errors: yes表示当该任务执行失败时,忽略当前任务,继续向下执行

[student@workstation control-flow]$ vim plalbook.yml
---
- name: restart http service
  hosts: servera.lab.example.com
  tasks:
    - name: httpd installed
      ansible.builtin.dnf:
        name: http     #将服务名写错
        state: present
      ignore_errors: yes  #当该任务执行失败后,继续向下执行

    - name: httpd started
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: true
    - name: reset index.html
      ansible.builtin.copy:
        content: "huazi\n"
        dest: /var/www/html/index.html
      notify: restart httpd

  handlers:
    - name: restart httpd
      ansible.builtin.service:
        name: httpd
        state: restarted
[student@workstation control-flow]$ ansible-navigator run -m stdout plalbook.yml

PLAY [restart http service] ****************************************************

TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]

TASK [httpd installed] *********************************************************
fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "failures": ["No package http available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring

TASK [httpd started] ***********************************************************
ok: [servera.lab.example.com]

TASK [reset index.html] ********************************************************
ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************
servera.lab.example.com    : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1

block,rescue,always

  • 如果block里面的任务成功执行,则忽略后面的rescue里面的任务,但影响always里面的任务
  • block,rescue,alwaystasks参数的下一级,但在模块上一级block,rescue,always有一个同级name参数,用于描述任务

changed_when

changed_when: false表示实际上远程主机没有被更改

包含文件与导入文件

  • 包含文件是一个动态操作,在playbook运行期间,ansible会在内容到达时处理所包含的内容
  • 导入文件是一个静态操作,在运行开始之前ansible在最初解析playbook预处理导入的内容

import_tasks import_playbook include_tasks

[student@workstation projects-file]$ cat playbook.yml
---
- name: confiure web server
  hosts: servera.lab.example.com
  tasks:
    - name: include the environment task file
      include_tasks: tasks/environment.yml
      vars:
        package: httpd
        service: httpd
    - name: import the
      import_tasks: tasks/firewall.yml
      vars:
        firewall_pkg: firewalld
        firewall_svc: firewalld
        rule:
          - http
          - https

      name: import the placeholder
      import_tasks: tasks/placeholder.yml
      vars:
        file: /var/www/html/index.html

- name: import test play
  import_playbook: plays/test.yml
  vars:
    url: 'http://servera.lab.example.com'

角色

  • 角色本质上也是一个目录

  • 简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们

在这里插入图片描述

Roles 内各目录含义解释:

  • files:用来存放由 copy 模块或 script 模块调用的文件
  • templates:用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件
  • tasks:此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件
  • handlers:此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作
  • vars:此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量
  • defaults:此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量
  • meta:此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系
[student@workstation role-create]$ ansible-galaxy init myvhost     #在当前目录下创建myvhost角色


[student@workstation role-create]$ ll
drwxr-xr-x. 10 student student 154 Aug 17 17:21 myvhost

Ansible中,ansible-galaxy 命令是一个用于管理Ansible角色的工具。通过该命令,你可以安装、删除、列出或搜索Ansible Galaxy中的角色。在你提供的命令中:

ansible-galaxy role install -r roles/requirements.yml -p roles/

这个命令执行了以下操作:

  • ansible-galaxy role install:这是安装角色的子命令。
  • -r roles/requirements.yml:这个选项指定了一个包含角色需求列表的文件(YAML格式)。Ansible Galaxy将从这个文件中读取需要安装的角色及其版本(如果指定了的话)。这里的文件路径是roles/requirements.yml,意味着Ansible将在当前目录的roles子目录下查找这个文件。
  • -p roles/:这个选项指定了安装角色的目标目录。在这个例子中,所有安装的角色都将被放置在当前目录的roles子目录下。这是一个很好的做法,因为它可以帮助你组织和管理你的项目中的Ansible角色。

列出角色

[devops@workstation ansible]$ ansible-galaxy role list
# /home/devops/ansible/roles
- balancer, (unknown version)
- phpinfo, (unknown version)

运行角色

[devops@workstation ansible]$ vim selinux.yml
---
- name: setup selinux policy
  hosts: all
  vars:
    selinux_policy: targeted
    selinux_state: enforcing
  roles:  #任务在角色中,所以在playbook中只需设定任务需要的vars参数和指定roles
    - redhat.rhel_system_roles.selinux
[devops@workstation ansible]$ ansible-navigator run -m stdout selinux.yml

安装collection

ansible-galaxy collection install 包路径 --force

列出colection

ansible-galaxy collection list

pre_tasks post_tasks

  • pre_tasks:在playbook执行tasks之前执行
  • post_tasks:在所有tasks执行后执行
  • tasks具有相同的性质

总结

  • when中的变量不用{{ }}包裹
  • debugvar参数的变量不用{{ }}包裹
  • .j2文件中的变量需要用{{}}包裹
  • firewalld模块和mount模块用的是ansible.posix集合
  • filesystem模块和parted模块和lvol模块和lvg模块用的是community.general集合
  • 其他常用模块用的是ansible.builtin集合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2076855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PTA团体程序设计天梯赛

这次题目出得比前几次简单很多,但有几道题占用的时间太多,导致后面几题仓促写完,未能全部正确,还是得多练 目录 L1-2 九牛一毛 L1-3 小孩子才做选择,大人全都要 L1-5 试试手气 L1-6 打PTA L1-8 随机输一次 L2-…

QT5.15.2加载mysql驱动-QMYSQL driver not loaded解决方法

Available drivers: "QSQLITE" "QODBC" "QODBC3" "QPSQL" "QPSQL7" QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7 源码下载(若存在&#xff0…

029集—CAD VBA识别“Esc”退出键——vba代码实现

vba程序运行时我们想按下“Esc”键时退出程序或做出进一步相应, 此时可借助windows API函数实现。 见下图: 部分代码如下: #If VBA7 Then 64位系统声明Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)…

【C++从练气到飞升】16---二叉搜索树

🎈个人主页:库库的里昂 ✨收录专栏:C从练气到飞升 🎉鸟欲高飞先振翅,人求上进先读书🎉 目录 ⛳️推荐 一、二叉搜索树概念 二、二叉搜索树的操作 2.1 二叉搜索树的查找 2.2 二叉搜索树的插入 2.3 二叉…

Linux基础 - yum、rzsz、vim 使用与配置、gcc/g++的详细解说

目录 一、Linux 软件包管理器 yum A.什么是软件包? B.关于rzsz,yum的配置 1.安装 sz,rz 命令: a.执行命令sz可将linux中的文件传输到Windows中 b.执行rz命令可将Windows中的文件传输到linux 2.scp XXX.tgz 用户名另一台lin…

BCLinux Euler 21.10 安装mysql 8.0.37 (二进制安装)

下载mysql安装包 #根据ldd --version的信息, 下载的是glic 2.28的包。 下载地址:https://downloads.mysql.com/archives/community/ 包名:mysql-8.0.37-linux-glibc2.28-x86_64.tar.xz#root用户操作 #系统环境:BigCloud Enterpri…

注册安全分析报告:助通信息

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…

Python操作ES

代码说明: 连接 Elasticsearch:使用 basic_auth 参数进行认证。测试连接:获取集群的健康状态,并格式化输出结果。索引文档:将一个文档索引到指定的索引中,并格式化输出结果。搜索文档:在指定的…

【python计算机视觉编程——2.局部图像描述子】

python计算机视觉编程——2.局部图像描述子 2.局部图像描述子2.1 Harris角点检测器在图像间寻找对应点 2.2 SIFT(尺度不变特征变换)2.2.3 检测兴趣点2.2.4 匹配描述子 2.3 匹配地理标记图像 2.局部图像描述子 2.1 Harris角点检测器 算法步骤 计算图像梯…

JS New Worker() 深度解析

JS New Worker() 深度解析 文章目录 一、New Worker() 是什么及为什么出现二、JS中如何使用 New Worker()1. 创建 Worker 线程2. 向 Worker 发送消息3. 接收 Worker 的消息4. 监听错误和结束事件5. 终止 Worker 三、Worker 包含哪些属性或方法 API1. 属性2. 方法 四、扩展与高级…

customRef 与 ref

ref() 我们已经很熟悉了,就是用来定义响应式数据的,其底层原理还是通过 Object.defineprotpty 中的 get 实现收集依赖( trackRefValue 函数收集),通过 set 实现分发依赖通知更新( triggerRefValue 函数分发 )。我们看看 ref 的源码就知道了 …

适合学生党用的充电宝有哪些?四款百元性价比充电宝推荐

在如今这个电子设备不离手的时代,充电宝成为了学生党们的必备好物。无论是在教室、图书馆学习,还是外出游玩,一款可靠的充电宝能够为手机、平板等设备随时补充电量,让你不再为电量焦虑而烦恼。今天,我们就为学生党们精…

AES对称加密算法

1. 简介 AES是一种对称加密算法, 它有3种类型: AES-128: 密钥为128位(16字节)的AES, 加密10轮AES-192: 密钥为192位(24字节)的AES, 加密12轮AES-256: 密钥为256位(32字节)的AES, 加密14轮 密钥长度越长, 加密的强度越大, 当然与此同时开销也越大。每种类型下都有几种操作模式…

【JavaEE】深入浅出 Spring AOP:概念、实现与原理解析

目录 Spring AOPAOP概述Spring AOP快速⼊⻔引⼊AOP依赖编写AOP程序 Spring AOP 详解Spring AOP核⼼概念切点(Pointcut)连接点(Join Point)通知(Advice)切⾯(Aspect) 通知类型PointCut切⾯优先级 Order切点表达式execution表达式annotation⾃定义注解 MyAspect切⾯类添加⾃定义注…

力扣第71题:简化路径 放弃栈模拟,选择数据流√(C++)

目录 题目 思路 解题过程 复杂度 Code 题目 给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 / 开头),请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中,一个点&#xff…

K8S持久化存储数据volumeMountsvolumes

环境: Ubuntu-1:192.168.114.110作为主 Ubuntu-2:192.168.114.120作为从1,node节点1 Ubuntu-3:192.168.114.130作为从2,node节点2 持久化volumeMounts pod里面:emptyDir和hostPath。存储在node,NFS...,Clo…

文本处理函数

1.文本的提取 left mid right 2.文本的查找与替换 replace,substitute 3.字符个数 len字符 lenb字节, office365好像没有此功能 4.数据的清理 clean , trim 5.找不同 exact

codetop标签动态规划大全C++讲解(上)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

主要供自己回顾学习,会持续更新,题源codetop动态规划近半年 1.零钱兑换2.零钱兑换II3.面试题08.11.硬币4.单词拆分5.最长递增子序列6.最长递增子序列的个数7.得到山形数组的最少删除次数8.最长公共子序列9.最长重复子数组10.最长等差数列11.最大子数组和…

智能优化算法-海鸥优化算法(SOA)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍: 海鸥优化算法 (Seagull Optimization Algorithm, SOA) 是一种基于群体智能的元启发式优化算法,它模拟了海鸥的觅食、飞行和社会交互行为,用于解决复杂的优化问题。 SOA的工…

wxpython Scintilla styledtextctrl滚动条拖到头文本内容还有很多的问题

wxpython Scintilla styledtextctrl滚动条拖到头文本内容还有很多的问题 使用wxpython Scintilla styledtextctrl,滚动条不自动更新 滚动条拖到头文本内容还有很多,如下: 以下是拖到最后的状态: 明显看出下图的滚动条的格子比…