Ansible git module ใช้ clone และ pull repository จาก Git server ไปยัง remote server โดยตรงใน Playbook โดยไม่ต้องรัน command: git clone ตรง ๆ ซึ่งไม่ idempotent และต้องจัดการ error handling เอง
บทความนี้ครอบคลุม parameters หลัก, การ clone และ update repository, การกำหนด branch/tag/commit, การใช้ SSH key สำหรับ private repository, การ deploy code ด้วย symlink pattern และ pattern สำหรับ automated deployment workflow
git Module พื้นฐาน
git module ต้องการ parameter repo (URL ของ repository) และ dest (path ที่จะ clone ไป) เป็นอย่างน้อย ถ้า directory ปลายทางมี repository อยู่แล้ว module จะ pull แทน clone อัตโนมัติ
---
- name: Basic git module usage
hosts: all
become: true
tasks:
# clone public repository
- name: Clone application repository
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: main
# update ถ้ามีอยู่แล้ว, clone ถ้ายังไม่มี
- name: Clone or update repository
git:
repo: https://github.com/example/config.git
dest: /etc/myapp/config
version: production
update: true # default คือ true
# ไม่ update ถ้ามีอยู่แล้ว (idempotent แบบ strict)
- name: Clone once, never update
git:
repo: https://github.com/example/tools.git
dest: /opt/tools
update: false
version — Branch, Tag และ Commit
parameter version รับค่าได้หลายรูปแบบ ทั้ง branch name, tag name และ commit hash ทำให้ควบคุม codebase ที่ deploy ได้อย่างแม่นยำ
---
- name: version parameter examples
hosts: all
become: true
tasks:
# deploy จาก branch ชื่อ release
- name: Clone release branch
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: release/v2
# deploy จาก tag (fixed version)
- name: Clone specific tag
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp/releases/v2.5.0
version: v2.5.0
# deploy จาก commit hash ตายตัว (reproducible build)
- name: Clone specific commit
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp/releases/stable
version: a1b2c3d4e5f6789012345678901234567890abcd
# ใช้ variable กำหนด version (จาก extra vars หรือ vars file)
- name: Deploy specified version
git:
repo: "{{ app_repo_url }}"
dest: "/opt/{{ app_name }}/releases/{{ app_version }}"
version: "{{ app_version }}"
Private Repository — SSH Key Authentication
สำหรับ private repository ที่ต้องการ authentication ใช้ key_file กำหนด SSH private key path บน remote server หรือใช้ accept_hostkey เพื่อ auto-accept host key ครั้งแรก
---
- name: Private repository access
hosts: all
become: true
vars:
deploy_key_path: /home/deploy/.ssh/deploy_key
tasks:
# copy deploy key ไปยัง remote server ก่อน
- name: Copy deploy SSH key
copy:
src: files/deploy_key
dest: "{{ deploy_key_path }}"
owner: deploy
group: deploy
mode: '0600'
# clone private repo ด้วย SSH key
- name: Clone private repository
git:
repo: [email protected]:example/private-app.git
dest: /opt/private-app
version: main
key_file: "{{ deploy_key_path }}"
accept_hostkey: true
become_user: deploy
# ใช้ HTTPS พร้อม token (เก็บใน Vault)
- name: Clone with HTTPS token
git:
repo: "https://{{ github_token }}@github.com/example/private-app.git"
dest: /opt/private-app
version: main
force และ depth
force: true ใช้เมื่อต้องการล้าง local changes ก่อน pull และ depth ใช้ทำ shallow clone เพื่อประหยัด bandwidth และ disk space บน server
---
- name: force and depth options
hosts: all
become: true
tasks:
# force: ล้าง local changes แล้ว pull ใหม่
- name: Force update repository
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: main
force: true # git reset --hard แล้ว pull
# shallow clone — ดึงเฉพาะ history ล่าสุด N commits
- name: Shallow clone (faster for CI)
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: main
depth: 1 # ดึงแค่ commit ล่าสุด
# ไม่ clone submodules (default)
- name: Clone with submodules
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: main
recursive: true # clone submodules ด้วย
register — ตรวจสอบว่า Repository เปลี่ยนแปลงหรือไม่
ใช้ register กับ git module เพื่อตรวจว่ามีการเปลี่ยนแปลงจริงหรือไม่ แล้วนำผลไปใช้ใน conditional tasks เช่น trigger restart เฉพาะเมื่อ code เปลี่ยน
---
- name: Register git changes
hosts: all
become: true
tasks:
- name: Pull latest code
git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: main
register: git_result
- name: Show git result
debug:
msg:
- "Changed: {{ git_result.changed }}"
- "Before: {{ git_result.before }}"
- "After: {{ git_result.after }}"
# รัน build เฉพาะเมื่อ code เปลี่ยน
- name: Run build script
command: /opt/myapp/scripts/build.sh
when: git_result.changed
# restart service เฉพาะเมื่อ code เปลี่ยน
- name: Restart application
service:
name: myapp
state: restarted
when: git_result.changed
Pattern: Deploy Code ด้วย Release Directory และ Symlink
Pattern มาตรฐานสำหรับ zero-downtime deployment คือ clone ลงใน release directory ที่มี timestamp แล้วสลับ symlink current ไปชี้ release ใหม่ ทำให้ rollback ง่ายโดยแค่ย้าย symlink กลับ
---
- name: Deploy with release directory pattern
hosts: appservers
become: true
vars:
app_name: myapp
app_repo: https://github.com/example/myapp.git
app_version: "{{ deploy_version | default('main') }}"
release_dir: "/opt/{{ app_name }}/releases/{{ ansible_date_time.epoch }}"
current_link: "/opt/{{ app_name }}/current"
shared_dir: "/opt/{{ app_name }}/shared"
tasks:
# สร้าง release directory
- name: Create release directory
file:
path: "{{ release_dir }}"
state: directory
owner: deploy
group: deploy
mode: '0755'
# clone code ลงใน release directory
- name: Clone application code
git:
repo: "{{ app_repo }}"
dest: "{{ release_dir }}"
version: "{{ app_version }}"
depth: 1
force: true
become_user: deploy
register: git_result
# link shared directories (logs, uploads, config)
- name: Link shared directories
file:
src: "{{ shared_dir }}/{{ item }}"
dest: "{{ release_dir }}/{{ item }}"
state: link
force: true
loop:
- logs
- uploads
- config/database.yml
# รัน migrations ถ้า code เปลี่ยน
- name: Run database migrations
command: /opt/myapp/bin/migrate
args:
chdir: "{{ release_dir }}"
when: git_result.changed
become_user: deploy
# สลับ symlink ไปชี้ release ใหม่
- name: Switch current to new release
file:
src: "{{ release_dir }}"
dest: "{{ current_link }}"
state: link
force: true
# restart application
- name: Restart application service
service:
name: "{{ app_name }}"
state: restarted
สรุป
git module เป็นทางที่ถูกต้องในการ clone และ update repository ด้วย Ansible รองรับ branch, tag และ commit hash ผ่าน version, ใช้ SSH key สำหรับ private repository ผ่าน key_file และตรวจสอบการเปลี่ยนแปลงได้ผ่าน register
Pattern ที่ควรจำ: ใช้ depth: 1 เพื่อประหยัด bandwidth บน production server, ใช้ register เพื่อ trigger downstream tasks เฉพาะเมื่อ code จริง ๆ เปลี่ยน, ใช้ release directory + symlink pattern สำหรับ zero-downtime deployment และเก็บ SSH key หรือ token ใน Ansible Vault เสมอ

