-
Features:
-
Developed based on Python (paramiko), modular work
-
Communicates with remote hosts via SSH, no agent installation required on clients, only Ansible needs to be installed on the control node
-
Management Architecture
-
Inventory host list: List of managed host IPs, categorized
-
Ad-hoc: Command line batch management (ans module) for temporary tasks
-
Playbook mode: Similar to writing a script with several operations (task collection), allowing this script to be run repeatedly
-
Deployment
-
RHEL/Centos systems
# Install EPEL repository (Ansible is in the EPEL source)
sudo yum install -y epel-release
# Install Ansible
sudo yum install -y ansible
-
Ubuntu/Debian systems
# Update apt source
sudo apt update
# Install Ansible
sudo apt install -y ansible
-
Install via pip for any system
# Ensure pip is installed
sudo apt install -y python3-pip # Ubuntu/Debian
# or
sudo yum install -y python3-pip # RHEL/CentOS
# Install Ansible using pip
sudo pip3 install ansible
-
Verify installation, version information and configuration file path should appear
ansible --version
Offline Installation
Method 1: Pre-download RPM/DEB packages
# CentOS/RHEL
yum install --downloadonly --downloaddir=/tmp/ansible ansible
# Debian/Ubuntu
apt-get install --download-only ansible -y
Copy the /tmp/ansible directory to the internal network machine
Execute on the internal network
# CentOS/RHEL
yum localinstall -y /tmp/ansible/*.rpm
# Debian/Ubuntu
dpkg -i /tmp/ansible/*.deb
apt-get -f install -y
Method 2: Offline Python + pip packages
If you prefer to use pip
Execute on the external network machine:
pip download ansible-core==2.15.* -d /tmp/ansible-pkgs
pip download ansible==8.* -d /tmp/ansible-pkgs
Copy /tmp/ansible-pkgs to the internal network
Install on the internal network:
pip install --no-index --find-links=/tmp/ansible-pkgs ansible
Method 3: Directly package the virtual environment
Create venv on the external network:
python3 -m venv /opt/ansible-venv
source /opt/ansible-venv/bin/activate
pip install ansible
Package the entire <span>/opt/ansible-venv</span>, transfer to the internal network.
After unpacking on the internal network, use <span>bin/ansible</span>, <span>bin/ansible-playbook</span>.
Configuration File ansible.cfg
The pip installation does not include the default ansible.cfg configuration file.
# You can specify the default configuration file when using commands
ansible [command parameters] --config /path/to/your/ansible.cfg
-
The priority order for recognizing the default configuration file during ansible execution is as follows:
When you execute the <span>ansible --version</span> command, the current working directory is <span>/root/ansible/</span>.
The priority order for Ansible to find the configuration file (from high to low) is as follows:
-
Path specified by the command line using the
<span>--config</span>parameter (highest priority) -
Current working directory’s
<span>./ansible.cfg</span>(i.e., the directory you are in) -
User home directory’s
<span>~/.ansible.cfg</span> -
System-level configuration
<span>/etc/ansible/ansible.cfg</span>
The configuration file can also specify the location of the host inventory.
-
ans-inventory Host Inventory
Ansible defaults to reading the hosts file in /etc/ansible/hosts, and you can also place the inventory file in a specified directory, using the -i option when running ansible to specify the inventory file
# Password-based connection
[root@ansible ~]# vim /etc/ansible/hosts
# Method 1 Host+Port+Password
[webserver]
192.168.1.31 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
192.168.1.32 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
192.168.1.33 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
192.168.1.36 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123456"
# Method 2 Host+Port+Password
[webserver]
192.168.1.3[1:3] ansible_ssh_user=root ansible_ssh_pass="123456"
# Method 2 Host+Port+Password
[webserver]
192.168.1.3[1:3]
[webserver:vars]ansible_ssh_pass="123456"
# Key-based connection
After distributing the key, you do not need to put the password in the file for passwordless use
# Method 1 Host+Port+Key
[webserver]
192.168.1.31:2219
192.168.1.32
192.168.1.33
192.168.1.36
# Method 1 Alias Host+Port+Key
[webserver]
node1 ansible_ssh_host=192.168.1.31 ansible_ssh_port=22
node2 ansible_ssh_host=192.168.1.32 ansible_ssh_port=22
node3 ansible_ssh_host=192.168.1.33 ansible_ssh_port=22
node6 ansible_ssh_host=192.168.1.36 ansible_ssh_port=22
# Usage of Host Groups
# Host Group Variable Name+Host+Password
[apache]
192.168.1.36
192.168.1.33
[apache.vars]ansible_ssh_pass='123456'
# Host Group Variable Name+Host+Key
[nginx]
192.168.1.3[1:2]
# Define multiple groups, treating one group as members of another group
[webserver:children] # The webserver group includes two subgroups: apache nginx
apache
nginx
Temporarily Specify Inventory
-
First edit a host definition inventory
[root@ansible ~]# vim /etc/dockers
[dockers]
192.168.1.31 ansible_ssh_pass='123456'
192.168.1.32
192.168.1.33
-
Specify the
<span>inventory</span>when executing the command
[root@ansible ~]# ansible dockers -m ping -i /etc/dockers -o 192.168.1.33 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.32 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.31 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
Built-in Parameters of Inventory
-
Ansible Ad-hoc
Ad-hoc —— Temporary, in <span>ansible</span> refers to commands that need to be executed quickly and do not need to be saved. Simply put, it is executing simple commands — a single command. For complex commands, it is referred to as <span>playbook</span>, similar to the <span>saltstack</span> state file.
Ansible Command Format
Common Parameters:
# Common two formats
ansible -m shell -a "" -o
# inventory is the host list, the default configuration file is /etc/ansible/hosts, can execute in groups
-m followed by the module name, commonly used are shell, copy, etc.
-a followed by module parameters, for example, shell module followed by command, copy module followed by source path (src) and destination path (dest)
-C, --check # Check syntax
-f FORKS # Concurrency
--list-hosts # List host list
-o Use concise output
# Example
ansible webserver -m shell -a 'uptime' -o
192.168.1.36 | CHANGED | rc=0 | (stdout) 13:46:14 up 1 day, 9:20, 4 users, load average: 0.00, 0.00, 0.00
192.168.1.33 | CHANGED | rc=0 | (stdout) 21:26:33 up 1 day, 8:51, 3 users, load average: 0.00, 0.01, 0.05
192.168.1.31 | CHANGED | rc=0 | (stdout) 21:26:33 up 1 day, 8:50, 3 users, load average: 0.00, 0.01, 0.05
192.168.1.32 | CHANGED | rc=0 | (stdout) 21:26:33 up 1 day, 8:59, 3 users, load average: 0.00, 0.01, 0.05
Command Explanation:
Host Group Matching:
# Group configuration information as follows: Here defines a nginx group and an apache group
[root@ansible ~]# ansible nginx --list hosts (2): 192.168.1.31 192.168.1.32
[root@ansible ~]# ansible apache --list hosts (3): 192.168.1.36 192.168.1.33 192.168.1.32
# Match all hosts in one group
[root@ansible ~]# ansible apache -m ping
# Match all hosts that are in apache group but not in nginx group
[root@ansible ~]# ansible 'apache:!nginx' -m ping -o
192.168.1.36 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.33 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
# Match machines that are in both apache and nginx groups (intersection)
[root@ansible ~]# ansible 'apache:&nginx' -m ping -o
192.168.1.32 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
# Match all machines in both apache and nginx groups (union); equivalent to ansible apache,nginx -m ping
[root@ansible ~]# ansible 'apache:nginx' -m ping -o
192.168.1.32 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.31 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.33 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.1.36 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
-
Common Ansible Modules
-
Command Module
Default module, not as flexible and powerful as shell, but safer
-
Shell
Similar to command, executes commands using shell
# Modify configuration file to make shell the default module
vim /etc/ansible/ansible.cfg
module_name = shell
-
Script Module
Runs scripts on remote hosts from the ansible server
Example:<span>ansible websrvs -m script -a /data/test.sh</span>
-
Copy Module
Copy: Copies files from the control node to remote hosts
src: Source file, specifies the local path of the file to be copied (if there is a /, it copies the contents of the directory, not the directory itself)
dest: Specifies the target path
mode: Sets permissions
backup: If the target machine’s file exists, back up the source file before replacing it.
content: Replaces src, specifies the content of the local file, generating the target host file
Example: ansible all -m copy -a “src=./test.yml dest=/root/qwer/ backup=yes”
# Corresponding yml file - name: Copy file and enable backup copy: src: ./local_test.yml dest: /root/qwer/test.yml backup: yes # Enable backupansible websrvs -m copy -a “src=/root/test1.sh dest=/tmp/test2.sh owner=wang mode=600 backup=yes” If the target exists, it will overwrite by default, here it specifies to back up first
ansible websrvs -m copy -a “content=’test content\nxxx’ dest=/tmp/test.txt” Specifies content, directly generates the target file
-
Fetch Module
Fetch: Extracts files from remote hosts to the control node, opposite of copy, currently does not support directories.
ansible websrvs -m fetch -a ‘src=/root/test.sh dest=/data/scripts’
Will generate a directory with different numbers for each managed host, preventing filename conflicts
ansible all -m shell -a ‘tar jxvf test.tar.gz /root/test.sh’
ansible all -m fetch -a ‘src=/root/test.tar.gz dest=/data/’
-
Service Module
Manages services
ansible srv -m service -a 'name=httpd state=stopped' # Stop service
ansible srv -m service -a 'name=httpd state=started enabled=yes' # Start service and set to start on boot
ansible srv -m service -a 'name=httpd state=reloaded' # Reload
ansible srv -m service -a 'name=httpd state=restarted' # Restart service
-
Playbook Mode
<span>ansible-playbook -i <inventory path> <playbook file> <optional parameters></span>
Playbook Template Example
-
Playbook to Create Directory
---
- name: Create directory
hosts: all # Can split backend group (backend) and frontend group (frontend)
remote_user: root # User executing the deployment
vars:
backup_dir: "/opt/backup/{{ ansible_date_time.date }}" # Backup path (by date)
tasks:
# 1. Preparation: Create backup and temporary directories
- name: Create backup directory
file:
path: "{{ backup_dir }}"
state: directory
mode: '0755'