Playbook
通过ansible命令执行操作的方式 call ad-hoc
简单例子
在线playbook分享平台:https://galaxy.ansible.com
ansible tree ansible-nginx
ansible-nginx
├── files
│ └── nginx.conf.j2
└── playbook.yml
1 directory, 2 files
➜ ansible-nginx cat files/nginx.conf.j2
server {
listen 80;
root /tmp/;
index index.html index.htm;
server_name a.com;
location / {
default_type "text/html";
try_files $uri.html $uri $uri/ =404;
}
}
➜ ansible-nginx cat playbook.yml
---
- hosts: d11
name: playbook demo
become: yes
gather_facts: false
remote_user: root
become_user: root
tasks:
- name: Update apt cache and install Nginx
apt:
name: nginx
state: latest
update_cache: yes
- name: Apply Nginx template
template:
src: files/nginx.conf.j2
dest: /etc/nginx/sites-available/default
notify: Restart Nginx
- name: Enable new site
file:
src: /etc/nginx/sites-available/default
dest: /etc/nginx/sites-enabled/default
state: link
notify: Restart Nginx
- name: Allow all access to tcp port 80
ufw:
rule: allow
port: '80'
proto: tcp
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
ansible-playbook -C playbook.yml
ansible-playbook playbook.yml
galaxy.ansible
找几个例子看看
https://galaxy.ansible.com/andrewrothstein/java-oracle-jdk
https://galaxy.ansible.com/sansible/golang
#快速创建role文件与目录
ansible ansible-galaxy init --init-path playbooks/roles web
- Role web was created successfully
➜ ansible
ansible tree playbooks/roles/web
playbooks/roles/web
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
基本语法
变量
---
- name: Install Apache on Ubuntu using variables
hosts: web # 替换成你的目标主机组名或主机名
become: true # 以特权用户执行任务
vars:
apache_package: apache2
apache_service: apache2
tasks:
- name: Install Apache
ansible.builtin.package:
name: "{{ apache_package }}"
state: present
- name: Start and enable Apache service
ansible.builtin.service:
name: "{{ apache_service }}"
state: started
enabled: true
---
- name: Remove the apache package
hosts: evan
become: true # 以特权用户执行任务
vars:
apache_package: apache2
apache_service: apache2
tasks:
- name: Remove the apache package
ansible.builtin.package:
name: "{{ apache_package }}"
state: absent
3.4.4 条件语句 when
#如果是debian类,关机
playbooks cat when.yml
---
- name: shtudown
hosts: pi3
tasks:
- name: shutdown if debian
command: /sbin/shutdown -t now
when: ansible_os_family =="Debian"
#更加好的例子
---
- name: Install vim
hosts: all
tasks:
- name:Install VIM via yum
yum:
name: vim-enhanced
state: installed
when: ansible_os_family =="RedHat"
- name:Install VIM via apt
apt:
name: vim
state: installed
when: ansible_os_family =="Debian"
- name: Unexpected OS family
debug: msg="OS Family {{ ansible_os_family }} is not supported" fail=yes
when: not ansible_os_family =="RedHat" or ansible_os_family =="Debian"
*************
利用when 判断文件在不在
- name: Execute task only if a file exists
hosts: evan
tasks:
- name: Check if file exists
stat:
path: /tmp/myfile.txt
register: file_check
- name: Do something if file exists
debug:
msg: "File /tmp/myfile.txt exists!"
when: file_check.stat.exists
PLAY [Execute task only if a file exists] ****************************************************
TASK [Gathering Facts] ***********************************************************************
ok: [192.168.10.74]
ok: [192.168.10.93]
TASK [Check if file exists] ******************************************************************
ok: [192.168.10.74]
ok: [192.168.10.93]
TASK [Do something if file exists] ***********************************************************
skipping: [192.168.10.74]
skipping: [192.168.10.93]
PLAY RECAP ***********************************************************************************
192.168.10.74 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.10.93 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
ansible evan -m shell -a "touch /tmp/myfile.txt"
touch 文件之后
TASK [Do something if file exists] *****************************************************************************************************
ok: [192.168.10.74] => {
"msg": "File /tmp/myfile.txt exists!"
}
ok: [192.168.10.93] => {
"msg": "File /tmp/myfile.txt exists!"
}
3.4.5循环控制
Loops (循环)
使用 loop 或 with_items 可以在 Playbook 中进行循环操作。
一般书上都是用with_item
cat loop-user2.yml
---
- name: create user
hosts: pi3
tasks:
- name: create user
user:
name: "{{ item }}"
state: present
with_items:
- user04
- user05
- user06
- name: set password
shell: echo 'e12345678' | passwd --stdin "{{ item }}"
with_items:
- user04
- user05
- user06
➜ ansible cat loop-user.yml
---
- name: create user
hosts: pi3
tasks:
- name: create user
user:
name: "{{ item }}"
state: present
loop:
- user01
- user02
- user03
- name: set password
shell: echo 'e12345678' | passwd --stdin "{{ item }}"
loop:
- user01
- user02
- user03
ansible-playbook -C loop-user.yml
ansible-playbook loop-user.yml
执行后查看结果
root@mypi3b:~# cat /etc/passwd | grep user
root@mypi3b:~#
root@mypi3b:~# cat /etc/passwd | grep user
user01:x:1003:1004::/home/user01:/bin/sh
user02:x:1004:1005::/home/user02:/bin/sh
user03:x:1005:1006::/home/user03:/bin/sh
root@mypi3b:~# su - user01
$ hostname
mypi3b
$ id
uid=1003(user01) gid=1004(user01) groups=1004(user01)
利用loop 安装多个软件 例如 os init etc
- name: Install multiple packages
hosts: evan
become: yes
vars:
packages:
- vim
- wget
tasks:
- name: Install packages using loop
package:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
3.4.6 include语法
playbook中代码复用非常爽,eg task
---
- tasks:
- include: a.yml user=root
- include: b.yml user=root
- include: c.yml user=root
或者是下面的多个项目用一个脚本的例子
➜ playbooks cat restart_ng.yml
- name: Restart ng Server
service:
name: nginx
state: restarted
➜ playbooks cat a.yml
- hosts: pi3
tasks:
- name: A Project command
command: echo "A"
- name: Restart ng
include: restart_ng.yml
➜ playbooks cat b.yml
- hosts: mytmp
tasks:
- name: A Project command
command: echo "A"
- name: Restart ng
include: restart_ng.yml
ansible-playbook a.yml
ansible-playbook b.yml
成功执行后 查看结果
nsible pi3 -m shell -a "systemctl status nginx"
192.168.10.5 | CHANGED | rc=0 >>
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-08-24 12:59:57 CST; 3min ago
Inlcude结合tags应用
”include”不仅能够引用任务列表,还能够引用playbook,比如,在一个playbook中引用另一个playbook。
示例:通过指定标签 tags ,来说明是安装 tomcat8 还是 tomcat9
1.准备入口 main.yml 文件,然后包含 install_tomcat8.yml 以及install_tomcat9.yml
2.在执行 main.yml 时,需要通过 --tags 指明要安装的版本
3.还可以在主playbook文件中向引用的playbook传递变量。
编写main.yml入口文件:
# cat tomcat_main.yml
- name: Install Tomcat8
import_playbook: install_tomcat8.yml
tags: tomcat8
vars:
tomcat_version: 8.5.69
tomcat_install_path: /usr/local
- name: Install Tomcat9
import_playbook: install_tomcat9.yml
tags: tomcat9
vars:
tomcat_version: 9.0.50
tomcat_install_path: /usr/local
编写install_tomcat8.yml文件
cat install_tomcat8.yml
---
- hosts: localhost
tasks:
- name: Install JDK
yum:
name: java-1.8.0-openjdk
state: present
- name: Download Tomacat
get_url:
url: https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz
dest: /root
- name: Unarchive Tomcat
unarchive:
src: /root/apache-tomcat-{{ tomcat_version }}.tar.gz
dest: "{{ tomcat_install_path }}"
- name: Create Link File
file:
src: "{{ tomcat_install_path }}/apache-tomcat-{{ tomcat_version }}"
dest: "{{ tomcat_install_path }}/tomcat8"
state: link
- name: Start Tomcat
shell: cd "{{ tomcat_install_path }}"/tomcat8/bin && nohup ./startup.sh &
编写install_tomcat9.yml文件:
cat install_tomcat9.yml
---
- hosts: localhost
tasks:
- name: Install JDK
yum:
name: java-1.8.0-openjdk
state: present
- name: Download Tomacat
get_url:
url: https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz
dest: /root
- name: Unarchive Tomcat
unarchive:
src: /root/apache-tomcat-{{ tomcat_version }}.tar.gz
dest: "{{ tomcat_install_path }}"
- name: Create Link File
file:
src: "{{ tomcat_install_path }}/apache-tomcat-{{ tomcat_version }}"
dest: "{{ tomcat_install_path }}/tomcat9"
state: link
- name: Start Tomcat
shell: cd "{{ tomcat_install_path }}"/tomcat9/bin && nohup ./startup.sh &
#安装tomcat9
[root@xuzhichao playbook]# ansible-playbook -t tomcat9 tomcat_main.yml
#安装tomcat8
[root@xuzhichao playbook]# ansible-playbook -t tomcat8 tomcat_main.yml
https://blog.51cto.com/u_15127516/3557509
[Ansible系列]ansible-playbook之include和import
pre-tasks and post-tasks
---
- hosts: www
remote_user: vagrant
sudo: yes
pre_tasks:
- name: update the apt cache
apt: update_cache=yes
- shell: echo 'I":" Beginning to configure web server..'
roles:
- nginx
post_tasks:
- shell: echo 'I":" Done configuring nginx web server...'
https://www.oreilly.com/library/view/ansible-playbook-essentials/9781784398293/ch02s09.html
Handlers (处理程序)
Handlers 是一种特殊的任务,只有在其他任务发生更改时才会被触发。常用于在配置文件更改后重启服务。
例如ng config
---
- name: Example with handlers
hosts: all
become: yes
tasks:
- name: Copy configuration file
copy:
src: /path/to/config.conf
dest: /etc/config.conf
owner: root
group: root
mode: '0644'
notify:
- Restart MyService
handlers:
- name: Restart MyService
service:
name: myservice
state: restarted
常用 role 及playbook 例子
Ansible Roles Roles 是组织 Playbooks 和相关文件的一种方式,可以提高代码的可重用性和可维护性。
Roles 的结构
一个典型的 Role 包含以下目录结构:
roles/
└── <role_name>/
├── tasks/
│ └── main.yml # 主要任务
├── handlers/
│ └── main.yml # 处理程序
├── vars/
│ └── main.yml # 变量定义
├── defaults/
│ └── main.yml # 默认变量定义
├── meta/
│ └── main.yml # Role 的元数据
├── files/ # 静态文件
├── templates/ # Jinja2 模板文件
└── tasks/ # 包含更小的任务文件
创建和使用 Roles
创建 Role 目录结构:
Bash
ansible-galaxy init <role_name>
这将创建一个基本的 Role 目录结构。
在 Playbook 中使用 Role:
YAML
---
- name: Deploy My Application
hosts: webservers
become: yes
roles:
- common # 调用名为 common 的 Role
- { role: apache, version: 2.4 } # 调用 apache Role 并传递变量
- myapp
在 Role 的 tasks/main.yml 中定义任务:
YAML
- name: Install required packages
package:
name: "{{ item }}"
state: present
loop: "{{ common_packages }}"
- name: Configure application
template:
src: "{{ app_config_template }}"
dest: "{{ app_config_path }}"
owner: appuser
group: appgroup
mode: '0644'
notify:
- Restart Application Service
在 Role 的 vars/main.yml 中定义变量:
playbook role 安装golang
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html
https://www.redhat.com/en/topics/automation/what-is-an-ansible-role
Why use an Ansible Role instead of an Ansible Playbook?
Ansible Roles and Ansible Playbooks are both tools for organizing and executing automation tasks, but each serves a different purpose. Whether you choose to create Ansible Roles or write all of your tasks in an Ansible Playbook depends on your specific use case and your experience with Ansible.
Most automation developers and system administrators begin creating automation content with individual playbooks. A playbook is a list of automation tasks that execute for a defined inventory. Tasks can be organized into a play—a grouping of 1 or more tasks mapped to a specific host and executed in order. A playbook can contain 1 or more plays, offering a flexible mechanism for executing Ansible automation in a single file.
While playbooks are a powerful method for automating with Ansible, writing all of your tasks in a playbook isn’t always the best approach. In instances where scope and variables are complex and reusability is helpful, creating most of your automation content in Ansible Roles and calling them within a playbook may be the more appropriate choice.
The following example illustrates the use of a role, linux-systemr-roles.timesync, within a playbook. In this instance, over 4 tasks would be required to achieve what the single role accomplishes.
pre config
#pre config cat /etc/ansible/ansible.cfg [defaults] inventory = /home/evan/ansible/inventory/hosts roles_path = /home/evan/ansible/playbooks/roles cat ~/ansible/inventory/hosts [mytmp] 192.168.10.7 ansible_user=root
目录
├── go.yml ├── roles │ └── go_install │ ├── files │ │ └── go1.17.1.linux-amd64.tar.gz │ ├── tasks │ │ ├── copy.yml │ │ ├── install.yml │ │ └── main.yml │ └── templates │ └── go_install.sh
文件详情
cat go.yml
---
- name: Installing Go from source
hosts: mytmp
remote_user: root
roles:
- go_install
**********
cat copy.yml
- name: copy go_tgz to client
copy: src=/home/evan/ansible/playbooks/roles/go_install/files/go1.17.1.linux-amd64.tar.gz dest=/usr/local/src/
- name: copy install_go_script to client
copy: src=/home/evan/ansible/playbooks/roles/go_install/templates/go_install.sh dest=/tmp/go_install.sh owner=root group=root mode=755
cat install.yml
- name: install go
shell: /bin/bash /tmp/go_install.sh
cat main.yml
- include_tasks: copy.yml
- include_tasks: install.yml
cat templates/go_install.sh
#!/bin/bash
# install golang
# yum tools
yum -y groupinstall "Development tools"
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
cd /usr/local/src
tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
source /etc/profile
# end
install zabbix-agent2
ansible-playbook -C zabbix-agent2.yml
ansible-playbook zabbix-agent2.yml
cat /etc/ansible/zabbix-agent2.yml
---
- hosts: mytmp
become: yes
become_method: sudo
remote_user: evan
#remote_user: ops
roles:
- ag2_conf
cat /etc/ansible/roles/ag2_conf/tasks/copy.yml
- name: copy install__script to client
copy: src=/etc/ansible/roles/ag2_conf/templates/age2_install.sh dest=/tmp/age2_install.sh owner=root group=root mode=755
cat /etc/ansible/roles/ag2_conf/tasks/install.yml
- name: install conig zbx agent2
shell: /bin/bash /tmp/age2_install.sh
cat /etc/ansible/roles/ag2_conf/tasks/main.yml
- include_tasks: copy.yml
- include_tasks: install.yml
cat /etc/ansible/roles/ag2_conf/templates/age2_install.sh
#!/bin/bash
sudo yum remove zabbix-agent -y
sudo /usr/bin/rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
sudo sleep 5
sudo /usr/bin/yum install zabbix-agent2 -y
sudo sleep 5
#bak cong
sudo sed -i 's/127.0.0.1/172.16.0.42/g' /etc/zabbix/zabbix_agent2.conf #/etc/zabbix/zabbix_agent2.conf
sudo cp /etc/zabbix/zabbix_agent2.conf /etc/zabbix/zabbix_agent2.confbakevan
sudo sed -i "s/Hostname=Zabbix server/Hostname=${HOSTNAME}/g" /etc/zabbix/zabbix_agent2.conf
#grep "^\s*[^# \t].*$" /etc/zabbix/zabbix_agent2.conf
sudo systemctl enable zabbix-agent2.service
sudo systemctl restart zabbix-agent2
install and remove nginx on ubuntu
- name: apt nginx
hosts: evan
become: yes
tasks:
- name: update
apt: update_cache=yes
- name: Install Nginx
apt: name=nginx state=latest
notify:
- restart nginx
handlers:
- name: restart nginx
service: name=nginx state=reloaded
---
- name: Remove Nginx from Ubuntu
hosts: evan
become: true
tasks:
- name: Stop Nginx service
service:
name: nginx
state: stopped
- name: Remove Nginx package
apt:
name: nginx
state: absent
purge: true
- name: Remove Nginx configuration directories
file:
path: "{{ item }}"
state: absent
loop:
- /etc/nginx
- /var/log/nginx
reboot playbook
---
- name: Reboot servers
hosts: evan
tasks:
- name: Reboot the servers
ansible.builtin.reboot:
msg: "Rebooting the server for system updates"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: uptime
https://docs.ansible.org.cn/ansible/latest/collections/ansible/builtin/reboot_module.html
refer
通过ansible安装中间件(jdk,nginx,mysql,etcd集群)
(playbook ins zbx还不错) ansible自动化运维详细教程及playbook详解
How to Install Nginx using Ansible Playbook
官网参考文档:
loops: https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
filters: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html