349 lines
7.5 KiB
Markdown
349 lines
7.5 KiB
Markdown
# File Deployment & GitOps Management
|
|
|
|
A simple, generic Ansible-based system to deploy and manage files on multiple servers using Git as the single source of truth.
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This repository uses **Ansible** to:
|
|
- **Deploy** files from Git to target servers
|
|
- **Check Drift** to ensure servers stay in sync with the repository
|
|
- **Validate** that deployed files are correct
|
|
|
|
No rsyslog-specific code. Just simple file deployment that works for any file or service.
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
.
|
|
├── README.md # This file
|
|
├── ansible.cfg # Ansible configuration
|
|
├── .woodpecker.yml # CI/CD pipeline configuration
|
|
│
|
|
├── ansible/
|
|
│ ├── inventory/
|
|
│ │ ├── hosts.yml # Define target servers
|
|
│ │ └── group_vars/
|
|
│ │ └── all.yml # Global variables (SSH credentials, etc.)
|
|
│ │
|
|
│ └── playbooks/
|
|
│ ├── apply.yml # Deploy file to servers
|
|
│ ├── drift-check.yml # Check if servers are in sync with repo
|
|
│ └── validate.yml # Verify file exists on server
|
|
│
|
|
└── files/
|
|
└── dvir.txt # The file to deploy (edit this to your needs)
|
|
```
|
|
|
|
---
|
|
|
|
## How It Works (Simple Version)
|
|
|
|
1. **You edit the file** in `files/dvir.txt`
|
|
2. **You commit to Git** (the source of truth)
|
|
3. **Run `apply.yml`** to deploy to all servers
|
|
4. **Run `drift-check.yml`** anytime to verify servers match Git
|
|
5. **If drift is detected**, run `apply.yml` again to fix it
|
|
|
|
That's it!
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### 1. Edit the file you want to deploy
|
|
|
|
Open `files/dvir.txt` and add your content:
|
|
|
|
```bash
|
|
nano files/dvir.txt
|
|
```
|
|
|
|
To deploy a **different file**, rename it or update the paths in the playbooks.
|
|
|
|
### 2. Add target servers
|
|
|
|
Edit `ansible/inventory/hosts.yml`:
|
|
|
|
```yaml
|
|
all:
|
|
children:
|
|
servers:
|
|
hosts:
|
|
server1:
|
|
ansible_host: 192.168.10.161
|
|
server2:
|
|
ansible_host: 192.168.10.162
|
|
```
|
|
|
|
### 3. Run the playbooks
|
|
|
|
#### Deploy the file:
|
|
```bash
|
|
ansible-playbook ansible/playbooks/apply.yml
|
|
```
|
|
|
|
#### Check if servers are in sync:
|
|
```bash
|
|
ansible-playbook ansible/playbooks/drift-check.yml
|
|
```
|
|
|
|
#### Validate file on server:
|
|
```bash
|
|
ansible-playbook ansible/playbooks/validate.yml
|
|
```
|
|
|
|
---
|
|
|
|
## Playbook Breakdown
|
|
|
|
### `apply.yml` - Deploy Files
|
|
**What it does:**
|
|
- Copies `files/dvir.txt` to `/tmp/dvir.txt` on all target servers
|
|
- Sets file ownership to `root:root` with permissions `0644`
|
|
|
|
**When to use:**
|
|
- Initial deployment of the file
|
|
- After updating the file in Git
|
|
|
|
**Example:**
|
|
```bash
|
|
ansible-playbook ansible/playbooks/apply.yml
|
|
```
|
|
|
|
---
|
|
|
|
### `drift-check.yml` - Detect Configuration Drift
|
|
**What it does:**
|
|
- Reads the file from the Git repository (local)
|
|
- Reads the file from each target server (`/tmp/dvir.txt`)
|
|
- Compares the content byte-for-byte
|
|
- Reports `SYNCED` or `OUT_OF_SYNC`
|
|
|
|
**When to use:**
|
|
- Verify servers match the repository state
|
|
- Detect if someone manually changed the file on the server
|
|
- Run periodically (via cron or CI/CD) to monitor compliance
|
|
|
|
**Example:**
|
|
```bash
|
|
ansible-playbook ansible/playbooks/drift-check.yml
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
✓ dvir.txt is synced # Files match
|
|
✗ dvir.txt is out of sync # Files differ or file missing
|
|
```
|
|
|
|
---
|
|
|
|
### `validate.yml` - Validate Deployment
|
|
**What it does:**
|
|
- Checks that `/tmp/dvir.txt` exists on the server
|
|
- Verifies the file is readable
|
|
- Fails if the file is missing or not readable
|
|
|
|
**When to use:**
|
|
- After running `apply.yml` to verify success
|
|
- To confirm the deployment was successful
|
|
|
|
**Example:**
|
|
```bash
|
|
ansible-playbook ansible/playbooks/validate.yml
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
### Inventory: `ansible/inventory/hosts.yml`
|
|
Define which servers to manage:
|
|
|
|
```yaml
|
|
all:
|
|
children:
|
|
servers:
|
|
hosts:
|
|
server1:
|
|
ansible_host: 192.168.10.161
|
|
server2:
|
|
ansible_host: 192.168.10.162
|
|
```
|
|
|
|
### Global Variables: `ansible/inventory/group_vars/all.yml`
|
|
SSH and connection settings:
|
|
|
|
```yaml
|
|
ansible_user: root
|
|
ansible_ssh_private_key_file: "~/.ssh/id_rsa"
|
|
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
|
|
```
|
|
|
|
### Ansible Config: `ansible.cfg`
|
|
Global Ansible settings (host checking, plugins, etc.)
|
|
|
|
---
|
|
|
|
## Workflow Examples
|
|
|
|
### Example 1: Deploy a new file
|
|
|
|
```bash
|
|
# 1. Edit the file
|
|
echo "new config content" > files/dvir.txt
|
|
|
|
# 2. Commit to Git
|
|
git add files/dvir.txt
|
|
git commit -m "Update deployment file"
|
|
git push
|
|
|
|
# 3. Deploy to servers
|
|
ansible-playbook ansible/playbooks/apply.yml
|
|
|
|
# 4. Verify success
|
|
ansible-playbook ansible/playbooks/validate.yml
|
|
```
|
|
|
|
### Example 2: Monitor for drift (continuous compliance)
|
|
|
|
```bash
|
|
# Run drift check periodically (cron job)
|
|
0 */6 * * * cd /path/to/repo && ansible-playbook ansible/playbooks/drift-check.yml
|
|
```
|
|
|
|
### Example 3: Detect and fix manual changes
|
|
|
|
```bash
|
|
# Someone manually edited /tmp/dvir.txt on server1
|
|
# Check for drift
|
|
ansible-playbook ansible/playbooks/drift-check.yml
|
|
# Output: ✗ dvir.txt is out of sync
|
|
|
|
# Restore from Git
|
|
ansible-playbook ansible/playbooks/apply.yml
|
|
|
|
# Verify it's fixed
|
|
ansible-playbook ansible/playbooks/drift-check.yml
|
|
# Output: ✓ dvir.txt is synced
|
|
```
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- **Ansible** installed on your machine
|
|
- **SSH access** to all target servers (password or key-based)
|
|
- **Root or sudo access** on target servers (for writing to `/tmp`)
|
|
|
|
### Install Ansible
|
|
|
|
```bash
|
|
# macOS
|
|
brew install ansible
|
|
|
|
# Ubuntu/Debian
|
|
apt-get install ansible
|
|
|
|
# RHEL/CentOS
|
|
yum install ansible
|
|
|
|
# Python pip
|
|
pip install ansible
|
|
```
|
|
|
|
---
|
|
|
|
## Customization
|
|
|
|
### Deploy to a different path
|
|
|
|
Edit `ansible/playbooks/apply.yml`:
|
|
|
|
```yaml
|
|
- name: Copy file to destination
|
|
copy:
|
|
src: ../../files/dvir.txt
|
|
dest: /your/custom/path/filename.txt # ← Change this
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
```
|
|
|
|
### Deploy multiple files
|
|
|
|
Add more tasks to `apply.yml`:
|
|
|
|
```yaml
|
|
- name: Copy file 1
|
|
copy:
|
|
src: ../../files/dvir.txt
|
|
dest: /tmp/dvir.txt
|
|
|
|
- name: Copy file 2
|
|
copy:
|
|
src: ../../files/another.txt
|
|
dest: /tmp/another.txt
|
|
```
|
|
|
|
### Use different target servers
|
|
|
|
Edit `hosts.yml` and use:
|
|
|
|
```bash
|
|
ansible-playbook ansible/playbooks/apply.yml -i ansible/inventory/hosts.yml --limit "server2"
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### "SSH connection refused"
|
|
- Check `ansible_host` is correct in `hosts.yml`
|
|
- Verify SSH key in `group_vars/all.yml`
|
|
- Test manually: `ssh -i ~/.ssh/id_rsa root@192.168.10.161`
|
|
|
|
### "Permission denied" on deployment
|
|
- Ensure `become: true` is in the playbook
|
|
- Verify user has sudo access
|
|
- Check SSH key has correct permissions: `chmod 600 ~/.ssh/id_rsa`
|
|
|
|
### Drift check shows "out of sync" but I didn't change anything
|
|
- File permissions or ownership might have changed
|
|
- Line endings (CRLF vs LF) might differ
|
|
- The server file might be missing
|
|
|
|
### Can't read file on server
|
|
- Check `/tmp/dvir.txt` exists: `ls -la /tmp/dvir.txt`
|
|
- Verify permissions: `stat /tmp/dvir.txt`
|
|
- Ensure file is readable: `cat /tmp/dvir.txt`
|
|
|
|
---
|
|
|
|
## Tips & Best Practices
|
|
|
|
1. **Always commit before deploying**
|
|
- Use Git as the single source of truth
|
|
- Never manually edit `/tmp/dvir.txt` on servers
|
|
|
|
2. **Run drift-check regularly**
|
|
- Use cron or CI/CD to monitor compliance
|
|
- Alert on `OUT_OF_SYNC` status
|
|
|
|
3. **Test in dev first**
|
|
- Add a `dev` group in `hosts.yml`
|
|
- Test playbooks on dev servers before prod
|
|
|
|
4. **Use version control for everything**
|
|
- Keep all changes in Git
|
|
- Easy rollback: just revert and re-run `apply.yml`
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT (or your preferred license)
|