ansible自动化运维(4)

##管理变量和事实:练习:使用基本身份认证的httpd
[root@workstation~]#mkdir westos
[root@workstationwestos]#cat ansible.cfg

[defaults]
inventory=./inventory

[root@workstationwestos]#cat inventory

[webservers]
serverb.lab.example.com

#写playbook

---
- name: Webserver vars
  hosts: webservers
  vars:
    firewall_pkg: firewalld
    firewall_srv: firewalld
    web_pkg: httpd
    web_srv: httpd
    ssl_pkg: mod_ssl
    httpdconf_src: files/httpd.conf
    httpdconf_dest: /etc/httpd/conf/httpd.conf
    secrets_dir: /etc/httpd/secrets
    secrets_src: files/htpasswd
    secrets_dest: "{{ secrets_dir }}/htpasswd"
    web_root: /var/www/html
  tasks:
    - name: Install packages
      yum:
        name:
          - "{{ firewall_pkg }}"
          - "{{ web_pkg }}"
          - "{{ ssl_pkg }}"
        state:latest
    - name: Configure service
      copy:
        src: "{{ httpdconf_src }}"
        dest: "{{ httpdconf_dest }}"
        owner: root
        group: root
        mode: 0644
    - name: Create secrets directory
      file:
        path: "{{ secrets_dir }}"
        state: directory
        owner: apache
        group: apache
        mode: 0500
    - name: Create htpasswd
      copy:
        src: "{{ secrets_src }}"
        dest: "{{ secrets_dest }}"
        owner: apache
        group: apache

        mode: 0400
    - name: Create index.html
      copy:
        content: "{{ ansible_facts['fqdn'] }} ({{ ansible_facts['all_ipv4_addresses'] }})\n"
        dest: "{{ web_root}}/index.html"
    - name: Configure firewalld service
      service:
        name: "{{ firewall_srv }}"
        state: started
        enabled: true
    - name: Firewalld permit https
      firewalld:
        service: https
        state: enabled
        immediate: true
        permanent: true
    - name: Configure apache service
      service:
        name: "{{ web_srv }}"
        state: started
        enabled: true
- name: Test apache
  hosts: localhost
  become: no
  vars:
    - web_user: admin
  vars_files:
    - vars/secret.yml
  tasks:
    - name: Connect to apache with auth
      uri:
        url: https://serverb.lab.example.com
        validate_certs: no
        force_basic_auth: yes
        user: "{{ web_user }}"
        password: "{{ web_pass }}"       #定义了访问apache的用户密码
        return_content: yes
        status_code: 200
      register: auth_test
    - debug:
        var: auth_test.content

#创建加密文件

[root@workstationwestos]#mkdir vars
[root@workstationwestos]#ansible-vault create vars/secret.yml
New Vault password: 'redhat'
Confirm New Vault password: 'redhat'

在文件中写入:

web_pass:redhat
#创建files目录
[root@workstationwestos]#mkdir files
[root@workstationfiles]#ls
htpasswd httpd.conf
[root@serverb~]#htpasswd -cm htpasswd admin
[root@workstationfiles]#vim httpd.conf

134 <Directory "/var/www/html">
135       AuthUserFile      /etc/httpd/secrets/htpasswd
136       AuthType          basic
137       AuthName          "Please input your name and password!!"
138       Require user      admin
139
140       Require           valid-user


#交互式输入密码,进行语法检测
[root@workstationwestos]#ansible-playbook --syntax-check --vault-id @prompt playbook.yml
Vaultpassword(default):
playbook:playbook.yml
#执行
[root@workstationwestos]#ansible-playbook --vault-id @prompt playbook.yml
#总结

1.变量能够让playbook复用
2.可以给清单中的主机和主机组定义变量
3.可以使用事实和外部文件定义变量,也可以在命令行中
4.register关键字何以用于捕获命令输出
5.ansiblevault
6.ansible事实是从受管主机自动检测到的变量

##########实施任务控制##########
#####编写循环和条件任务######
##简单循环
1.不用循环

---
- name: test
  hosts: webservers
  tasks:
    - name: apache is running
      service:
        name: httpd
        state: started
    - name: vsftpd is running
      service:
        name: vsftpd
        state:started

2.使用循环

---
- name: test
  hosts: webservers
  tasks:
    - name: apache and vsftpd are running
      service:
        name: "{{ item }}"    #循环变量item
        state:started
      loop:
       - httpd
       - vsftpd

3.将变量放入列表

---
- name: test
  hosts: webservers
  vars:
    web_service:
      - httpd
      - vsftpd
  tasks:
    - name: apache and vsftpd are running
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ web_service }}"

##循环散列或字典列表

---
- name: User Test
  user:
    name: "{{ item.name }}"
    state: present
    groups: "{{ item.groups }}"
  loop:
    - name: westos
      groups: westos
    - name: redhat
      groups: root

##早些版本的循环,使用with_

    vars:
      data:
        - user1
        - user2
        - user3
    tasks:
      - name: "with_items"

    debug:
      msg: "{{ item }}"
      with_items: "{{ data }}"

##register和loop一起使用

[root@workstationloop]#cat loop_register.yml

---
- name: loop register test
  gather_facts: no
  hosts: localhost
  tasks:
    - name: loop echo task
      shell: "echo This is my item: {{ item }}"
      loop:
        - one
        - two
      register: echo_results       #注册变量
    - name: Show echo results variable
      debug:
        var: echo_results          #显示变量结果

##迭代上面playbook的结果(即使用上面item的结果)

---
- name: loop register test
  gather_facts: no
  hosts: localhost
  tasks:
    - name: loop echo task
      shell: "echo This is my item: {{ item }}"
      loop: 
        - one
        - two
      register: echo_results
    - name: Show echo results variable
      debug:
        msg: "STDOUT from previous task: {{ item.stdout }}"
      loop: "{{ echo_results['results'] }}"

##条件任务语法
关键字:when
使用布尔值测试

---
- name: Bool ean test
  hosts: all
  vars:
    run_my_task: true         #只有当变量为true时,才会执行
  tasks:
    - name: httpd is installed

      yum:
        name: httpd
      when: run_my_task

测试my_service变量是否有值,有值则安装

---
- name: Bool ean test
  hosts: all
  vars:
    my_service: httpd
  tasks: 
    - name: "{{ my_service }} is installed"
      yum: 
        name: "{{ my_service }}"
      when: my_service is defined

##条件

等于(字符串)         A == "B"
等于(数字)            A ==  100
小于                          <
大于                          >
小于等于                  <=
大于等于                  >=
不等于                      !=
变量存在                  xxx is defined
变量不存在              xxx is not defined
布尔值true               1、true、yes
布尔值false              0、false、no
第一个变量的值存在,且在第二个变量的列表中  A in B

##测试多个条件

or两个条件一个为真即可
and两个条件必须都为真

#when支持使用列表描述条件

when:
-ansible_distribution_version=="8.0"
-ansible_kernel=="4.18.0-80.1.2.el8_0.x86_64"
再如:
when:
(ansible_distribution=="RedHat"and
ansible_distribution_major_version=="8")
or

(ansible_distribution=="CentOS"and
ansible_distribution_major_version=="7")
这样写清晰
##组合循环和有条件任务
示例1:

---
- name: keyword
  hosts: all
  tasks:
    - name: install db if enough space
      yum:
        name: mariadb-server
        state: latest
      loop: "{{ ansible_mounts }}"         #这个变量是事实,已知的
      when: item.mount == "/" and item.size_available > 300000000

示例2:

---
- name: Restart httpd if vsftpd is running
  hosts: all
  tasks:
    - name: Get vsftpd status
      command: /usr/bin/systemctl is-active vsftpd     #判断状态
      ignore_errors: yes                              #如果vsftpd没运行或失败,则忽略
      register: result                                #定义变量保存结果
    - name: Restart httpd
      service:
        name: httpd
        state: restarted
      when: result.rc == 0                            #退出码为0,则重启httpd

##编写循环和条件任务:练习:
[root@workstation~]#mkdir control-flow
[root@workstationcontrol-flow]#cat ansible.cfg
[defaults]
inventory=./inventory
[root@workstationcontrol-flow]#cat inventory
[westos1]
servera.lab.example.com
[westos2]
serverb.lab.example.com
#写playbook

[root@workstationcontrol-flow]#catplaybook.yml

---
- name: Mariadb is running
  hosts: westos1
  vars:
    mariadb_pkgs:
     - mariadb-server
     - python3-PyMySQL
  tasks:
    - name: Mariadb is installed 
      yum:
        name: "{{ item }}"
        state: present
      loop: "{{ mariadb_pkgs }}"
    - name: Start Mariadb
      service:
        name: mariadb
        state: started
        enabled: true

#修改playbook,条件变为受管主机使用rehdat操作系统时才执行
[root@workstationcontrol-flow]#cat playbook.yml

---
- name: Mariadb is running
  hosts: westos2
  vars:
    mariadb_pkgs:
      - mariadb-server
      - python3-PyMySQL
  tasks:
    - name: Mariadb is installed
      yum:
        name: "{{ item }}"
        state: present
      loop: "{{ mariadb_pkgs }}"
      when: ansible_distribution == "RedHat"

#检测westos2组的主机系统

[root@workstationcontrol-flow]#ansible westos2 -m command -a 'cat /etc/redhat-release' -u student --become

serverb.lab.example.com | CHANGED | rc=0 >>
Red Hat Enterprise Linux release 8.0 (Ootpa)
#运行
[root@workstationcontrol-flow]#ansible-playbook playbook.yml·
PLAY[Mariadbisrunning]******************************************************
TASK[GatheringFacts]*********************************************************
ok:[serverb.lab.example.com]
TASK[Mariadbisinstalled]****************************************************
changed:[serverb.lab.example.com]=>(item=mariadb-server)
changed:[serverb.lab.example.com]=>(item=python3-PyMySQL)
PLAYRECAP*********************************************************************

serverb.lab.example.com:ok=2changed=1unreachable=0
failed=0skipped=0rescued=0ignored=0

######实施处理程序######

处理程序是响应由其他任务触发的通知的任务
#只有在template任务通知已发生更改时才会触发

---
- name: Test
  hosts: webservers
  tasks:
    - name: Copy File
      template:
        src: files/example.conf
        dest: /etc/httpd/conf.d/example.conf
      notify:                                    #notify语句指出该任务需要触发一个处理程序
        - restart apache                         #程序名
   handlers:                                     #表示处理程序任务列表的开头
     - name: restart apache                      #被任务调用的处理程序名称
       service:                                  #处理该程序的模块
         name: httpd
         state: restarted

#ansible把notify语句当作数组
[root@workstationcode]#mkdir files
[root@workstationcode]#cat files/example.conf

<VirtualHost *:80>
        DocumentRoot     /www
        ServerName       www.westos.org
</VirtualHost>

<VirtualHost *:80>
        DocumentRoot     /bbs
        ServerName       bbs.westos.org
</VirtualHost>

#写playbook
[root@workstationcode]#cat notify.yml

---
- name: Test
  hosts: webservers
  tasks:
    - name: Copy File
      template:
        src: files/example.conf
        dest: /etc/httpd/conf.d/example.conf
      notify:
        - restart apache
        - restart mysql

  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted
    - name: restart mysql
      service:
        name: mariadb
        state: restarted

#使用处理程序注意:

1.处理程序始终按照play的handlers部分指定的顺序运行,不按notify里的
2.处理程序通常在相关play中所有其他任务运行完后运行
3.处理程序名称存在于个play命名空间中(如果两个处理程序同名,只会运行一个)
4.如果多个任务通知处理程序,处理程序也只会运行一次
5.如果包含notify的语句任务没有报告changed结果,则处理程序不会获得通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值