在現代 DevOps 流程中,利用自動化工具來實現持續集成和持續部署(CI/CD)是提升開發效率的關鍵。Ansible 作為一個強大的配置管理工具,不僅可以簡化伺服器的配置,還能幫助我們輕鬆實現程式碼的部署。本文將介紹如何配置 Ansible ,以及使用 Ansible 將本地程式碼上傳到 Git 並部署到遠端伺服器。
程式範例#
Ansible 安裝與測試#
步驟 1:安裝 Ansible#
首先,你需要在本地機器上安裝 Ansible。你可以透過以下命令進行安裝:
在 Ubuntu 上安裝:
sudo apt update
sudo apt install ansible
在 MacOS 上安裝:
brew install ansible
步驟 2:設置 SSH 連接#
Ansible 需要能夠透過 SSH 連接到遠端伺服器。為了避免每次執行 Ansible 任務時都要手動輸入密碼,我們需要先確保本地機器與遠端伺服器之間建立了 SSH 信任關係。
- 使用以下命令生成 SSH 金鑰(如果還沒有):
- 使用 SSH 將本地機器的公鑰傳送到遠端伺服器:
- 完成上述步驟後,你應該可以無密碼地透過 SSH 連接到遠端伺服器。
步驟 3:準備 Ansible 清單文件#
在 Ansible 中,需要創建一個清單文件來指定目標伺服器。這個文件包含你的遠端伺服器的 IP 或主機名稱。這是清單文件的範例:
- inventory.ini
# 測試
[test_servers]
172.22.15.2 ansible_user=admin ansible_ssh_pass=changeme ansible_port=22 ansible_ssh_extra_args='-o StrictHostKeyChecking=no'
# 其他範例格式參考
[web_servers]
111.11.11.1 ansible_user=user1 ansible_ssh_pass=pass ansible_port=22 # 第一個主機
web2.example.com ansible_user=admin # 第二個主機
接著 ping 遠端主機,測試配置是否正確
ansible -i inventory.ini test_servers -m ping
若回傳以下訊息,則表示成功
172.22.15.2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong" # 有ping到
}
步驟 4:建立測試的 Ansible Playbook#
接下來,需要創建一個 Ansible Playbook 來定義部署任務。這是測試能否顯示遠端 硬碟容量 的 Playbook 範例:
- hello.yml
---
- name: Play with Ansible
hosts: test_servers
# become: yes
# become_user: root
# become_method: sudo
# hosts: localhost
tasks:
- name: Just execute df -h
ansible.builtin.command: df -h
register: output
changed_when: output.rc == 0
- name: Show stdout
ansible.builtin.debug:
msg: "{{ output.stdout_lines }}"
這段 Ansible Playbook 主要是執行兩個任務:
- 執行 df -h 命令並註冊結果
- 顯示 df -h 的標準輸出
步驟 5:執行 Ansible Playbook#
現在,你已經準備好執行 Playbook 了。使用以下命令來運行它:
ansible-playbook -i inventory.ini hello.yml
這段 Playbook 會連接到 test_servers 主機,執行 df -h 命令以查看磁碟空間使用情況,並將結果顯示出來
設定 Ansible : 部署本地程式碼到遠端伺服器#
在開始部署之前,我們需要先設定好相關的配置文件。這些配置文件將定義我們的 Git 儲存庫資訊、目標伺服器以及部署路徑。首先,讓我們從設定 Git 儲存庫資訊開始。
設定Git 儲存庫資訊#
repositories_vars.yaml
repositories:
- name: ansible_demo
url: https://github.com/a607ernie/ansible_demo.git
branch: master
user: admin # 替換為遠端電腦的使用者名稱
指定要部署的目標伺服器及其對應目錄路徑#
hosts_vars/web_server.yml
web_servers_git_path:
vars:
NEED_TO_CHANGE_THIS_git_repo_name: # git repo name , e.g. hello_git
REMOTE_HOST_IP: remote folder path # e.g. 111.11.11.1: /home/Documents/repo/
e.g.
web_servers_git_path:
vars:
ansible_demo:
11.111.111.11: /home/admin/Documents/ansible_demo/
# 可以加入更多主機
建立一個部署到遠端伺服器的 Ansible Playbook#
這是將本地程式碼上傳到 Git 並部署到遠端伺服器的 Playbook 範例
deploy.yml
---
- name: Git pull with Ansible
hosts: test_servers #可改,對應inventory.ini
# hosts: localhost
vars_files:
- ./repositories_vars.yml
- ./hosts_vars/web_servers.yml
vars:
git_repo: "{{ lookup('vars', selected_repo) }}"
# become: yes
# become_user: root
# become_method: sudo
tasks:
- name: Choose repo
set_fact:
git_repo: "{{ item }}"
loop: "{{ repositories }}"
when: item.name == "{{ selected_repo }}"
- name: Get path of remote host
set_fact:
dest_path: "{{ vars.web_servers_git_path.vars[git_repo.name][inventory_hostname] }}"
- name: Show the repo name
debug:
msg: "{{ git_repo }}"
- name: Check if destination path exists
stat:
path: "{{ dest_path }}"
register: dest_path_stat
- name: Clone the repository if the path does not exist
git:
repo: "{{ git_repo.url }}"
dest: "{{ dest_path }}"
version: "{{ git_repo.branch }}"
when: not dest_path_stat.stat.exists
- name: Fetch remote updates and prune old references
command: git fetch --prune origin
args:
chdir: "{{ dest_path }}"
when: dest_path_stat.stat.exists
- name: Ensure local branch tracks remote branch
command: git branch --set-upstream-to=origin/{{ git_repo.branch }} {{ git_repo.branch }}
args:
chdir: "{{ dest_path }}"
when: dest_path_stat.stat.exists
- name: Reset local branch to match remote
command: git reset --hard origin/{{ git_repo.branch }}
args:
chdir: "{{ dest_path }}"
when: dest_path_stat.stat.exists
- name: Clean untracked files
command: git clean -fd
args:
chdir: "{{ dest_path }}"
when: dest_path_stat.stat.exists
- name: Pull the latest changes from remote
git:
repo: "{{ git_repo.url }}"
dest: "{{ dest_path }}"
version: "{{ git_repo.branch }}"
update: yes
when: dest_path_stat.stat.exists
register: git_result
- name: Show git module output
debug:
msg: "Git module output: {{ git_result }}"
這段 Playbook 會將你的 Git 儲存庫複製到遠端伺服器的指定位置,然後運行一個部署腳本來完成部署。
執行部署到遠端伺服器的 Ansible Playbook#
這條命令會將本地程式碼從 Git 儲存庫 clone 到遠端伺服器並執行部署腳本。
ansible-playbook -i inventory.ini deploy.yml --extra-vars "selected_repo=YOUR_GIT_REPO_NAME"
e.g.
ansible-playbook -i inventory.ini deploy.yml --extra-vars "selected_repo=ansible_demo"
結論#
利用 Ansible 來自動化部署過程,你不僅能提高效率,還能減少手動操作的錯誤。無論是部署到一台伺服器還是多台伺服器,Ansible 都能幫助你輕鬆管理和擴展基礎設施。
