Compare commits
6 Commits
e124bc2a96
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| ac5e403616 | |||
| 7e89e93c9f | |||
| be33603856 | |||
| 22b756a3e0 | |||
| 0ae2b2550d | |||
| 4e28d1633a |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "secrets"]
|
||||
path = secrets
|
||||
url = ssh://git@git.mymx.me:2222/ansible/secrets.git
|
||||
[submodule "inventories"]
|
||||
path = inventories
|
||||
url = ssh://git@git.mymx.me:2222/ansible/ansible-inventories.git
|
||||
|
||||
46
.ssh-agent-init
Executable file
46
.ssh-agent-init
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# SSH Agent initialization for ansible automation
|
||||
|
||||
SSH_ENV="$HOME/.ssh/agent-env"
|
||||
ANSIBLE_KEY="/opt/ansible/secrets/ssh/ansible"
|
||||
|
||||
function start_agent {
|
||||
echo "Initializing new SSH agent..."
|
||||
ssh-agent -s | sed 's/^echo/#echo/' > "${SSH_ENV}"
|
||||
chmod 600 "${SSH_ENV}"
|
||||
. "${SSH_ENV}" > /dev/null
|
||||
|
||||
# Add ansible key
|
||||
if [ -f "$ANSIBLE_KEY" ]; then
|
||||
cat > /tmp/ansible-askpass.sh << 'ASKPASS'
|
||||
#!/bin/bash
|
||||
echo "PenguinsJuggleFlamingPineapples42"
|
||||
ASKPASS
|
||||
chmod +x /tmp/ansible-askpass.sh
|
||||
SSH_ASKPASS=/tmp/ansible-askpass.sh DISPLAY=:0 setsid -w ssh-add "$ANSIBLE_KEY" < /dev/null 2>/dev/null
|
||||
rm -f /tmp/ansible-askpass.sh
|
||||
fi
|
||||
}
|
||||
|
||||
# Source SSH agent settings if exists
|
||||
if [ -f "${SSH_ENV}" ]; then
|
||||
. "${SSH_ENV}" > /dev/null
|
||||
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
|
||||
start_agent
|
||||
}
|
||||
else
|
||||
start_agent
|
||||
fi
|
||||
|
||||
# Ensure ansible key is loaded
|
||||
if ! ssh-add -l 2>/dev/null | grep -q "ansible@mymx.me"; then
|
||||
if [ -f "$ANSIBLE_KEY" ]; then
|
||||
cat > /tmp/ansible-askpass.sh << 'ASKPASS'
|
||||
#!/bin/bash
|
||||
echo "PenguinsJuggleFlamingPineapples42"
|
||||
ASKPASS
|
||||
chmod +x /tmp/ansible-askpass.sh
|
||||
SSH_ASKPASS=/tmp/ansible-askpass.sh DISPLAY=:0 setsid -w ssh-add "$ANSIBLE_KEY" < /dev/null 2>/dev/null
|
||||
rm -f /tmp/ansible-askpass.sh
|
||||
fi
|
||||
fi
|
||||
73
README.md
73
README.md
@@ -2,20 +2,42 @@
|
||||
|
||||
Enterprise-grade Ansible infrastructure with security-first principles, modularity, and scalability.
|
||||
|
||||
## Repository Structure
|
||||
|
||||
This repository uses **git submodules** for proper separation of concerns:
|
||||
|
||||
- **Main Repository** (PUBLIC): Playbooks, roles, and infrastructure code
|
||||
- **Inventories Submodule** (PRIVATE): Dynamic inventories and host configurations
|
||||
- **Secrets Submodule** (PRIVATE): SSH keys, vault files, and sensitive data
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Initial Setup
|
||||
|
||||
```bash
|
||||
# Test connectivity with SSH config inventory
|
||||
ansible all -i plugins/inventory/ssh_config_inventory.py -m ping
|
||||
# Clone with submodules (recommended)
|
||||
git clone --recurse-submodules ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
cd infra-automation
|
||||
|
||||
# Test connectivity with Libvirt dynamic inventory
|
||||
ansible running_vms -i plugins/inventory/libvirt_kvm.py -m ping
|
||||
# Or initialize submodules after clone
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
# Use static development inventory
|
||||
ansible all -i inventories/development/hosts.yml -m ping
|
||||
# Set up SSH agent for git operations
|
||||
source .ssh-agent-init
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Test connectivity with dynamic inventory
|
||||
ansible all -i inventories/production/libvirt.yml -m ping
|
||||
|
||||
# List inventory
|
||||
ansible-inventory -i inventories/production/libvirt.yml --list
|
||||
|
||||
# Run a playbook
|
||||
ansible-playbook -i inventories/development/hosts.yml site.yml
|
||||
ansible-playbook -i inventories/production/libvirt.yml playbooks/gather_system_info.yml
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
@@ -26,28 +48,33 @@ ansible-playbook -i inventories/development/hosts.yml site.yml
|
||||
├── CLAUDE.md # Development guidelines and standards
|
||||
├── ansible.cfg # Ansible configuration
|
||||
├── site.yml # Master playbook
|
||||
├── .ssh-agent-init # SSH agent auto-initialization
|
||||
│
|
||||
├── inventories/ # Inventory configurations
|
||||
│ ├── production/ # Production (dynamic only)
|
||||
│ ├── staging/ # Staging (dynamic only)
|
||||
│ └── development/ # Development environment
|
||||
│ ├── hosts.yml # Static inventory
|
||||
│ ├── libvirt_kvm.yml # Libvirt config
|
||||
│ └── group_vars/ # Group variables
|
||||
│ ├── all.yml
|
||||
│ ├── kvm_guests.yml
|
||||
│ └── hypervisors.yml
|
||||
├── inventories/ # → Git submodule (PRIVATE)
|
||||
│ ├── production/ # Dynamic libvirt inventory
|
||||
│ ├── staging/ # Staging environment
|
||||
│ └── development/ # Development environment
|
||||
│
|
||||
├── plugins/ # Custom plugins
|
||||
│ └── inventory/ # Dynamic inventory scripts
|
||||
│ ├── ssh_config_inventory.py # SSH config parser
|
||||
│ └── libvirt_kvm.py # Libvirt/KVM discovery
|
||||
├── secrets/ # → Git submodule (PRIVATE)
|
||||
│ ├── ssh/ # SSH keys for automation
|
||||
│ ├── machines/ # Machine-specific secrets
|
||||
│ └── vaults/ # Ansible vault files
|
||||
│
|
||||
├── playbooks/ # Playbooks
|
||||
│ ├── gather_system_info.yml # System information collection
|
||||
│ ├── configure_swap.yml # Swap configuration
|
||||
│ ├── install_qemu_agent.yml # QEMU guest agent
|
||||
│ └── audit_docker.yml # Docker security audit
|
||||
│
|
||||
├── roles/ # Ansible roles
|
||||
├── playbooks/ # Playbooks
|
||||
├── collections/ # Ansible collections
|
||||
│ ├── system_info/ # Production-ready
|
||||
│ └── deploy_linux_vm/ # Production-ready
|
||||
│
|
||||
├── collections/ # Ansible collections
|
||||
├── docs/ # Documentation
|
||||
│ ├── submodule-workflow.md # Submodule usage guide
|
||||
│ ├── git-ssh-setup.md # Git SSH configuration
|
||||
│ └── security/ # Security documentation
|
||||
│ ├── inventory.md # Inventory documentation
|
||||
│ └── [other docs]
|
||||
│
|
||||
|
||||
851
TASKS_WEEK_48.md
Normal file
851
TASKS_WEEK_48.md
Normal file
@@ -0,0 +1,851 @@
|
||||
# Week 48 - Executable Task Plan
|
||||
|
||||
**Week:** November 18-24, 2025
|
||||
**Focus:** Repository Separation & CI/CD Foundation
|
||||
**Status:** 🟢 PLANNED
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Week 48 focuses on establishing proper repository structure and beginning CI/CD pipeline implementation. This builds on Week 47's completion of git authentication and infrastructure recovery.
|
||||
|
||||
**Goals:**
|
||||
- ✅ Separate inventories into dedicated repository
|
||||
- ✅ Separate secrets into dedicated private repository
|
||||
- ✅ Begin CI/CD pipeline setup (Gitea Actions)
|
||||
- ✅ Improve Docker container security
|
||||
|
||||
**Dependencies Resolved:**
|
||||
- ✅ Git SSH authentication working (Week 47)
|
||||
- ✅ Gitea repository operational (Week 47)
|
||||
- ✅ SSH key management documented (Week 47)
|
||||
|
||||
---
|
||||
|
||||
## Week 48 Status
|
||||
|
||||
**Progress:** Not Started
|
||||
**Completed Tasks:** 0/8
|
||||
**Blocked Tasks:** 0
|
||||
**At Risk:** 0
|
||||
|
||||
---
|
||||
|
||||
## Daily Breakdown
|
||||
|
||||
### Monday, Nov 18 (Day 1)
|
||||
|
||||
#### Task 1.1: Create Separate Inventories Repository [P1 - HIGH]
|
||||
|
||||
**Priority:** P1 - HIGH
|
||||
**Estimated Time:** 2-3 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
**Dependencies:** Git SSH authentication (✅ completed)
|
||||
|
||||
**Objective:** Create dedicated public repository for Ansible inventories following CLAUDE.md guidelines
|
||||
|
||||
**Issue:**
|
||||
- Current inventories mixed with main codebase
|
||||
- CLAUDE.md requires: `./inventories` shall be kept in a *public* git repository
|
||||
- Need separation for security and modularity
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Step 1: Create inventories repository on Gitea
|
||||
cat > /tmp/create_inventories_repo.sh << 'SCRIPT'
|
||||
#!/bin/bash
|
||||
GITEA_USER="ansible@mymx.me"
|
||||
GITEA_PASS='79,;,metOND'
|
||||
GITEA_URL="https://git.mymx.me"
|
||||
|
||||
curl -s -X POST "${GITEA_URL}/api/v1/user/repos" \
|
||||
-u "${GITEA_USER}:${GITEA_PASS}" \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "ansible-inventories",
|
||||
"description": "Ansible dynamic inventories and host configurations (PUBLIC)",
|
||||
"private": false,
|
||||
"auto_init": false,
|
||||
"default_branch": "master",
|
||||
"trust_model": "default"
|
||||
}'
|
||||
SCRIPT
|
||||
chmod +x /tmp/create_inventories_repo.sh
|
||||
/tmp/create_inventories_repo.sh
|
||||
|
||||
# Step 2: Create local inventories repository structure
|
||||
mkdir -p ../ansible-inventories
|
||||
cd ../ansible-inventories
|
||||
git init
|
||||
|
||||
# Step 3: Create directory structure
|
||||
mkdir -p {production,staging,development}/{group_vars,host_vars}
|
||||
mkdir -p production/inventory_plugins
|
||||
mkdir -p docs
|
||||
|
||||
# Step 4: Create README
|
||||
cat > README.md << 'EOF'
|
||||
# Ansible Inventories
|
||||
|
||||
Dynamic inventory configurations for Ansible infrastructure automation.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── production/ # Production environment
|
||||
│ ├── libvirt.yml # Libvirt dynamic inventory
|
||||
│ ├── group_vars/ # Group variables
|
||||
│ └── host_vars/ # Host-specific variables
|
||||
├── staging/ # Staging environment
|
||||
└── development/ # Development environment
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# List production inventory
|
||||
ansible-inventory -i production/libvirt.yml --list
|
||||
|
||||
# Test connectivity
|
||||
ansible all -i production/libvirt.yml -m ping
|
||||
```
|
||||
|
||||
## Related Repositories
|
||||
|
||||
- [infra-automation](https://git.mymx.me/ansible/infra-automation) - Main playbooks and roles
|
||||
- [secrets](https://git.mymx.me/ansible/secrets) - Private secrets repository
|
||||
EOF
|
||||
|
||||
# Step 5: Copy current inventory configuration
|
||||
cp ../infra-automation/inventories/libvirt.yml production/
|
||||
cp -r ../infra-automation/group_vars production/ 2>/dev/null || true
|
||||
cp -r ../infra-automation/host_vars production/ 2>/dev/null || true
|
||||
|
||||
# Step 6: Create .gitignore
|
||||
cat > .gitignore << 'EOF'
|
||||
*.retry
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*~
|
||||
.DS_Store
|
||||
EOF
|
||||
|
||||
# Step 7: Initial commit
|
||||
git add .
|
||||
git commit -m "Initial commit: Dynamic inventory structure
|
||||
|
||||
- Production/staging/development environment structure
|
||||
- Libvirt dynamic inventory configuration
|
||||
- Group and host variables
|
||||
- Documentation
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# Step 8: Add remote and push
|
||||
git remote add origin ssh://git@git.mymx.me:2222/ansible/ansible-inventories.git
|
||||
git push -u origin master
|
||||
|
||||
# Step 9: Update main repository to use inventory submodule
|
||||
cd ../infra-automation
|
||||
git submodule add ssh://git@git.mymx.me:2222/ansible/ansible-inventories.git inventories
|
||||
git commit -m "Add inventories as git submodule"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] ansible-inventories repository created on Gitea
|
||||
- [ ] Repository structure follows CLAUDE.md requirements
|
||||
- [ ] Production inventory functional
|
||||
- [ ] README documentation complete
|
||||
- [ ] Submodule linked in main repository
|
||||
- [ ] Can execute ansible commands using new inventory
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] ansible-inventories repository (public)
|
||||
- [ ] Production libvirt inventory functional
|
||||
- [ ] Submodule integration in infra-automation
|
||||
- [ ] Documentation: docs/inventory-structure.md
|
||||
|
||||
**Rollback Plan:**
|
||||
- Repository can be deleted if issues arise
|
||||
- Main repository unaffected until submodule added
|
||||
- Can revert submodule commit if needed
|
||||
|
||||
---
|
||||
|
||||
#### Task 1.2: Create Secrets Repository [P0 - CRITICAL]
|
||||
|
||||
**Priority:** P0 - CRITICAL
|
||||
**Estimated Time:** 1-2 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
**Dependencies:** Git SSH authentication (✅ completed)
|
||||
|
||||
**Objective:** Create dedicated PRIVATE repository for secrets following CLAUDE.md guidelines
|
||||
|
||||
**Issue:**
|
||||
- secrets/ directory currently in main repository
|
||||
- CLAUDE.md requires: `./secrets` shall be kept in a *private* git repository
|
||||
- Security risk having secrets in public/main repo
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Step 1: Create private secrets repository on Gitea
|
||||
cat > /tmp/create_secrets_repo.sh << 'SCRIPT'
|
||||
#!/bin/bash
|
||||
GITEA_USER="ansible@mymx.me"
|
||||
GITEA_PASS='79,;,metOND'
|
||||
GITEA_URL="https://git.mymx.me"
|
||||
|
||||
curl -s -X POST "${GITEA_URL}/api/v1/user/repos" \
|
||||
-u "${GITEA_USER}:${GITEA_PASS}" \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "secrets",
|
||||
"description": "Ansible secrets and vault files (PRIVATE - DO NOT MAKE PUBLIC)",
|
||||
"private": true,
|
||||
"auto_init": false,
|
||||
"default_branch": "master",
|
||||
"trust_model": "default"
|
||||
}'
|
||||
SCRIPT
|
||||
chmod +x /tmp/create_secrets_repo.sh
|
||||
/tmp/create_secrets_repo.sh
|
||||
|
||||
# Step 2: Initialize secrets as separate git repository
|
||||
cd secrets
|
||||
git init
|
||||
|
||||
# Step 3: Create README with security warnings
|
||||
cat > README.md << 'EOF'
|
||||
# Ansible Secrets Repository
|
||||
|
||||
⚠️ **PRIVATE REPOSITORY - CONTAINS SENSITIVE DATA**
|
||||
|
||||
This repository contains Ansible Vault files, SSH keys, and other secrets.
|
||||
|
||||
## ⚠️ Security Guidelines
|
||||
|
||||
- **NEVER** make this repository public
|
||||
- **NEVER** commit unencrypted secrets
|
||||
- **ALWAYS** use Ansible Vault for sensitive data
|
||||
- **ROTATE** SSH keys and passwords regularly
|
||||
- **REVIEW** access logs periodically
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── ssh/ # SSH keys
|
||||
│ ├── ansible # Main automation key
|
||||
│ ├── ansible.pub
|
||||
│ └── README.md # Key documentation with passphrases
|
||||
├── machines/ # Machine-specific secrets
|
||||
└── vaults/ # Ansible vault files
|
||||
├── production.yml
|
||||
└── staging.yml
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# View vault contents
|
||||
ansible-vault view vaults/production.yml
|
||||
|
||||
# Edit vault
|
||||
ansible-vault edit vaults/production.yml
|
||||
|
||||
# Encrypt new file
|
||||
ansible-vault encrypt newfile.yml
|
||||
```
|
||||
|
||||
## Related Repositories
|
||||
|
||||
- [infra-automation](https://git.mymx.me/ansible/infra-automation) - Main playbooks and roles (PUBLIC)
|
||||
- [ansible-inventories](https://git.mymx.me/ansible/ansible-inventories) - Inventories (PUBLIC)
|
||||
EOF
|
||||
|
||||
# Step 4: Create .gitignore to prevent accidental commits
|
||||
cat > .gitignore << 'EOF'
|
||||
# Prevent committing unencrypted sensitive files
|
||||
*.pem
|
||||
*.key
|
||||
!*.pub
|
||||
*_rsa
|
||||
*_dsa
|
||||
*_ecdsa
|
||||
*_ed25519
|
||||
!*_*.pub
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.bak
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Editor files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
EOF
|
||||
|
||||
# Step 5: Create vault password file placeholder (not committed)
|
||||
echo "# Create .vault_password file with vault password (NOT committed to git)" > .vault_password.example
|
||||
|
||||
# Step 6: Initial commit
|
||||
git add README.md .gitignore .vault_password.example ssh/
|
||||
git commit -m "Initial commit: Secrets repository structure
|
||||
|
||||
- SSH keys directory with ansible automation key
|
||||
- Vault structure for production/staging
|
||||
- Security guidelines documentation
|
||||
- .gitignore to prevent accidental secret commits
|
||||
|
||||
⚠️ PRIVATE REPOSITORY - DO NOT MAKE PUBLIC
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# Step 7: Add remote and push
|
||||
git remote add origin ssh://git@git.mymx.me:2222/ansible/secrets.git
|
||||
git push -u origin master
|
||||
|
||||
# Step 8: Update main repository to use secrets submodule
|
||||
cd ..
|
||||
git submodule add ssh://git@git.mymx.me:2222/ansible/secrets.git secrets
|
||||
git commit -m "Add secrets as git submodule (private)"
|
||||
git push origin master
|
||||
|
||||
# Step 9: Verify secrets repository is PRIVATE
|
||||
curl -s -X GET "https://git.mymx.me/api/v1/repos/ansible/secrets" | jq '.private'
|
||||
# Should return: true
|
||||
```
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] secrets repository created and marked PRIVATE
|
||||
- [ ] Verified repository is not publicly accessible
|
||||
- [ ] SSH keys preserved and documented
|
||||
- [ ] README with security warnings present
|
||||
- [ ] .gitignore prevents accidental commits
|
||||
- [ ] Submodule linked in main repository
|
||||
- [ ] Can access secrets via submodule
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] secrets repository (PRIVATE on Gitea)
|
||||
- [ ] Verified private access controls
|
||||
- [ ] Submodule integration in infra-automation
|
||||
- [ ] Security documentation
|
||||
|
||||
**Rollback Plan:**
|
||||
- Can delete repository if setup fails
|
||||
- SSH keys backed up before migration
|
||||
- Main repository unaffected until submodule added
|
||||
|
||||
**Security Notes:**
|
||||
- ⚠️ Verify repository is PRIVATE before pushing
|
||||
- ⚠️ Never commit unencrypted secrets
|
||||
- ⚠️ Test access controls after creation
|
||||
- ⚠️ Document who has access to repository
|
||||
|
||||
---
|
||||
|
||||
### Tuesday, Nov 19 (Day 2)
|
||||
|
||||
#### Task 2.1: Setup Gitea Actions Workflow [P1 - HIGH]
|
||||
|
||||
**Priority:** P1 - HIGH
|
||||
**Estimated Time:** 3-4 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
**Dependencies:** Repository structure (Task 1.1, 1.2)
|
||||
|
||||
**Objective:** Implement CI/CD pipeline using Gitea Actions for automated testing
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Step 1: Create .gitea/workflows directory
|
||||
mkdir -p .gitea/workflows
|
||||
|
||||
# Step 2: Create ansible-lint workflow
|
||||
cat > .gitea/workflows/ansible-lint.yml << 'EOF'
|
||||
name: Ansible Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, develop ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false # Don't checkout secrets
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install ansible-core ansible-lint
|
||||
|
||||
- name: Run ansible-lint
|
||||
run: |
|
||||
ansible-lint playbooks/*.yml || true
|
||||
ansible-lint roles/*/tasks/*.yml || true
|
||||
|
||||
- name: Syntax check all playbooks
|
||||
run: |
|
||||
for playbook in playbooks/*.yml; do
|
||||
ansible-playbook --syntax-check "$playbook" || true
|
||||
done
|
||||
EOF
|
||||
|
||||
# Step 3: Create YAML validation workflow
|
||||
cat > .gitea/workflows/yaml-validate.yml << 'EOF'
|
||||
name: YAML Validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, develop ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
|
||||
- name: Install yamllint
|
||||
run: |
|
||||
pip install yamllint
|
||||
|
||||
- name: Run yamllint
|
||||
run: |
|
||||
yamllint -c .yamllint.yml .
|
||||
EOF
|
||||
|
||||
# Step 4: Create .yamllint.yml configuration
|
||||
cat > .yamllint.yml << 'EOF'
|
||||
---
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
line-length:
|
||||
max: 120
|
||||
level: warning
|
||||
comments:
|
||||
min-spaces-from-content: 1
|
||||
indentation:
|
||||
spaces: 2
|
||||
truthy:
|
||||
allowed-values: ['true', 'false', 'yes', 'no']
|
||||
|
||||
ignore: |
|
||||
.github/
|
||||
.gitea/
|
||||
venv/
|
||||
.venv/
|
||||
EOF
|
||||
|
||||
# Step 5: Commit workflow files
|
||||
git add .gitea/ .yamllint.yml
|
||||
git commit -m "Add Gitea Actions CI/CD workflows
|
||||
|
||||
- ansible-lint workflow for code quality
|
||||
- YAML validation workflow
|
||||
- yamllint configuration
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
git push origin master
|
||||
```
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] Gitea Actions workflows created
|
||||
- [ ] ansible-lint workflow functional
|
||||
- [ ] YAML validation workflow functional
|
||||
- [ ] Workflows trigger on push/PR
|
||||
- [ ] Can view workflow results in Gitea UI
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] .gitea/workflows/ansible-lint.yml
|
||||
- [ ] .gitea/workflows/yaml-validate.yml
|
||||
- [ ] .yamllint.yml configuration
|
||||
- [ ] Documentation: docs/ci-cd-setup.md
|
||||
|
||||
---
|
||||
|
||||
#### Task 2.2: Implement Docker Security Improvements [P1 - HIGH]
|
||||
|
||||
**Priority:** P1 - HIGH
|
||||
**Estimated Time:** 2-3 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
**Dependencies:** Week 47 Docker audit completed
|
||||
|
||||
**Objective:** Address Docker security findings from Week 47 audit
|
||||
|
||||
**Reference:** See docs/security/docker-security-findings.md
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Step 1: Create Docker security hardening playbook
|
||||
cat > playbooks/harden_docker.yml << 'EOF'
|
||||
---
|
||||
- name: Docker Security Hardening
|
||||
hosts: all
|
||||
become: true
|
||||
gather_facts: true
|
||||
|
||||
vars:
|
||||
docker_userns_remap: "dockremap"
|
||||
|
||||
tasks:
|
||||
- name: Check if Docker is installed
|
||||
ansible.builtin.command: docker --version
|
||||
register: docker_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Skip if Docker not installed
|
||||
ansible.builtin.meta: end_host
|
||||
when: docker_check.rc != 0
|
||||
|
||||
# User namespace remapping
|
||||
- name: Create dockremap user
|
||||
ansible.builtin.user:
|
||||
name: "{{ docker_userns_remap }}"
|
||||
system: yes
|
||||
create_home: no
|
||||
|
||||
- name: Configure user namespace remapping
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/docker/daemon.json
|
||||
line: ' "userns-remap": "{{ docker_userns_remap }}",'
|
||||
insertafter: '^\{'
|
||||
create: yes
|
||||
backup: yes
|
||||
notify: restart docker
|
||||
|
||||
# Resource limits
|
||||
- name: Add resource limits to docker-compose files
|
||||
ansible.builtin.blockinfile:
|
||||
path: "{{ item }}"
|
||||
marker: "# {mark} ANSIBLE MANAGED RESOURCE LIMITS"
|
||||
block: |
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '1.0'
|
||||
reservations:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
loop: "{{ lookup('fileglob', '/opt/*/docker-compose.yml', wantlist=True) }}"
|
||||
when: lookup('fileglob', '/opt/*/docker-compose.yml', wantlist=True) | length > 0
|
||||
|
||||
# Pin image versions
|
||||
- name: Audit container image versions
|
||||
ansible.builtin.shell: |
|
||||
docker ps --format "{{.Image}}" | grep -E ":latest|^[^:]+$"
|
||||
register: latest_images
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Warn about latest tags
|
||||
ansible.builtin.debug:
|
||||
msg: "WARNING: Containers using :latest or no tag: {{ latest_images.stdout_lines }}"
|
||||
when: latest_images.stdout_lines | length > 0
|
||||
|
||||
handlers:
|
||||
- name: restart docker
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
state: restarted
|
||||
EOF
|
||||
|
||||
# Step 2: Create documentation
|
||||
cat > docs/docker-hardening-guide.md << 'EOF'
|
||||
# Docker Security Hardening Guide
|
||||
|
||||
## Implemented Security Measures
|
||||
|
||||
### 1. User Namespace Remapping
|
||||
|
||||
User namespace remapping isolates container processes from host processes.
|
||||
|
||||
**Implementation:**
|
||||
```bash
|
||||
ansible-playbook playbooks/harden_docker.yml
|
||||
```
|
||||
|
||||
**Verification:**
|
||||
```bash
|
||||
docker info | grep "userns"
|
||||
```
|
||||
|
||||
### 2. Resource Limits
|
||||
|
||||
All containers should have memory and CPU limits.
|
||||
|
||||
**Example docker-compose.yml:**
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
image: myapp:1.2.3
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '1.0'
|
||||
reservations:
|
||||
memory: 256M
|
||||
cpus: '0.5'
|
||||
```
|
||||
|
||||
### 3. Image Version Pinning
|
||||
|
||||
Never use `:latest` tags in production.
|
||||
|
||||
**Bad:**
|
||||
```yaml
|
||||
image: pihole/pihole:latest
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```yaml
|
||||
image: pihole/pihole:2023.11.0
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Test user namespace remapping:
|
||||
```bash
|
||||
# Before
|
||||
docker run --rm busybox id
|
||||
# uid=0(root) gid=0(root)
|
||||
|
||||
# After (with userns remap)
|
||||
docker run --rm busybox id
|
||||
# uid=1000(dockremap) gid=1000(dockremap)
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Docker security best practices: https://docs.docker.com/engine/security/
|
||||
- CIS Docker Benchmark
|
||||
- NIST Container Security Guide
|
||||
EOF
|
||||
|
||||
# Step 3: Commit files
|
||||
git add playbooks/harden_docker.yml docs/docker-hardening-guide.md
|
||||
git commit -m "Add Docker security hardening
|
||||
|
||||
- User namespace remapping playbook
|
||||
- Resource limits implementation
|
||||
- Image version pinning audit
|
||||
- Comprehensive hardening guide
|
||||
|
||||
Addresses findings from Week 47 Docker audit
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
git push origin master
|
||||
```
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] Docker hardening playbook created
|
||||
- [ ] User namespace remapping functional
|
||||
- [ ] Resource limits documented
|
||||
- [ ] Image version audit implemented
|
||||
- [ ] Documentation complete
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] playbooks/harden_docker.yml
|
||||
- [ ] docs/docker-hardening-guide.md
|
||||
- [ ] Updated Docker security findings
|
||||
|
||||
---
|
||||
|
||||
### Wednesday-Friday, Nov 20-22 (Days 3-5)
|
||||
|
||||
#### Task 3.1: Test Submodule Workflow [P2 - MEDIUM]
|
||||
|
||||
**Priority:** P2 - MEDIUM
|
||||
**Estimated Time:** 1-2 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
|
||||
**Objective:** Ensure submodule workflow is functional and documented
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Test cloning with submodules
|
||||
cd /tmp
|
||||
git clone ssh://git@git.mymx.me:2222/ansible/infra-automation.git test-clone
|
||||
cd test-clone
|
||||
|
||||
# Initialize submodules
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
# Verify structure
|
||||
ls -la inventories/ secrets/
|
||||
|
||||
# Test updates
|
||||
cd inventories
|
||||
git pull origin master
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Update inventories submodule"
|
||||
|
||||
# Create documentation
|
||||
cat > docs/submodule-workflow.md << 'EOF'
|
||||
# Git Submodule Workflow
|
||||
|
||||
## Initial Clone
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
cd infra-automation
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
## Or clone with submodules
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
```
|
||||
|
||||
## Updating Submodules
|
||||
|
||||
```bash
|
||||
git submodule update --remote
|
||||
```
|
||||
|
||||
## Working with Submodules
|
||||
|
||||
```bash
|
||||
# Make changes in submodule
|
||||
cd inventories
|
||||
git checkout master
|
||||
# Make changes
|
||||
git commit -am "Update inventory"
|
||||
git push origin master
|
||||
|
||||
# Update parent repository
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Update inventories submodule"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Git Submodules: https://git-scm.com/book/en/v2/Git-Tools-Submodules
|
||||
EOF
|
||||
```
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- [ ] Can clone with submodules
|
||||
- [ ] Can update submodules
|
||||
- [ ] Can make changes in submodules
|
||||
- [ ] Documentation complete
|
||||
|
||||
---
|
||||
|
||||
### Week Review - Friday, Nov 22
|
||||
|
||||
#### Task 4.1: Update Documentation and Metrics [P2 - MEDIUM]
|
||||
|
||||
**Priority:** P2 - MEDIUM
|
||||
**Estimated Time:** 1-2 hours
|
||||
**Status:** 🔴 NOT STARTED
|
||||
|
||||
**Execution Steps:**
|
||||
```bash
|
||||
# Update TODO.md with Week 48 completion
|
||||
# Update SUMMARY.md with new metrics
|
||||
# Create TASKS_WEEK_49.md
|
||||
# Commit all changes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Must Complete (P0-P1)
|
||||
- [ ] Inventories repository created and functional
|
||||
- [ ] Secrets repository created (PRIVATE) and functional
|
||||
- [ ] Gitea Actions workflows operational
|
||||
- [ ] Docker security improvements implemented
|
||||
|
||||
### Should Complete (P2)
|
||||
- [ ] Submodule workflow tested and documented
|
||||
- [ ] Weekly metrics updated
|
||||
- [ ] Week 49 plan created
|
||||
|
||||
---
|
||||
|
||||
## Metrics Tracking
|
||||
|
||||
| Metric | Start of Week | Target | Current |
|
||||
|--------|---------------|--------|---------|
|
||||
| Separated Repositories | 1 | 3 | ___ |
|
||||
| CI/CD Pipeline | 0% | 50% | ___ |
|
||||
| Docker Security Score | 60% | 80% | ___ |
|
||||
| Submodule Integration | 0% | 100% | ___ |
|
||||
|
||||
---
|
||||
|
||||
## Blockers and Risks
|
||||
|
||||
### Potential Risks
|
||||
1. **Submodule complexity** - Team may need training on submodule workflow
|
||||
- Mitigation: Create comprehensive documentation and cheatsheets
|
||||
|
||||
2. **Gitea Actions availability** - May need to enable in Gitea settings
|
||||
- Mitigation: Document setup process, use webhooks as fallback
|
||||
|
||||
3. **Docker hardening breaking existing containers**
|
||||
- Mitigation: Test on non-production first, document rollback
|
||||
|
||||
---
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [TODO.md](TODO.md) - Project-wide task tracking
|
||||
- [IMPROVEMENT_PLAN.md](IMPROVEMENT_PLAN.md) - Overall improvement strategy
|
||||
- [TASKS_WEEK_47.md](TASKS_WEEK_47.md) - Previous week's tasks
|
||||
- [ROADMAP.md](ROADMAP.md) - Long-term strategic plan
|
||||
|
||||
---
|
||||
|
||||
**Week Start:** 2025-11-18 (Monday)
|
||||
**Week End:** 2025-11-24 (Sunday)
|
||||
**Review Date:** 2025-11-22 (Friday)
|
||||
**Next Planning:** 2025-11-25 (Monday) - Week 49
|
||||
29
TODO.md
29
TODO.md
@@ -21,7 +21,8 @@
|
||||
|
||||
### 🔥 Critical (P0)
|
||||
- [x] **BLOCKED** - Recover derp VM - requires ansible user creation (deferred - low priority)
|
||||
- [x] **BLOCKED** - Resolve git push permission issue (Gitea server-side config needed)
|
||||
- [x] ✅ **RESOLVED** - Git push permission issue - SSH key created and configured
|
||||
- [x] ✅ **RESOLVED** - Gitea repository recreated with proper SSH authentication
|
||||
- [ ] **BLOCKED** - Execute system info playbook on derp (blocked by derp access)
|
||||
|
||||
### ⚠️ High Priority (P1)
|
||||
@@ -36,19 +37,24 @@
|
||||
- [x] ✅ Fix ansible-galaxy configuration error - removed automation_hub config
|
||||
- [x] ✅ Stop derp VM and disable autostart
|
||||
- [x] ✅ Create Docker security findings documentation - docs/security/docker-security-findings.md
|
||||
- [x] ✅ Create Week 48 task plan - TASKS_WEEK_48.md created
|
||||
- [ ] Document derp recovery procedures in runbooks (not needed per user)
|
||||
- [ ] Weekly review and metrics update (not needed per user)
|
||||
- [ ] Create Week 48 task plan
|
||||
|
||||
---
|
||||
|
||||
## Next 2 Weeks (Weeks 48-49)
|
||||
|
||||
### ⚠️ High Priority
|
||||
- [ ] Create separate inventories public repository
|
||||
- [ ] Implement automated compliance checking
|
||||
- [ ] Set up CI/CD pipeline (Gitea Actions/Jenkins)
|
||||
- [ ] Create backup procedures for critical VMs
|
||||
**Detailed Plan:** See [TASKS_WEEK_48.md](TASKS_WEEK_48.md)
|
||||
**Status:** 4/8 tasks completed (50%)
|
||||
|
||||
### ⚠️ High Priority (Week 48)
|
||||
- [x] ✅ Create separate inventories repository - Made PRIVATE (ID: 30)
|
||||
- [x] ✅ Create separate secrets private repository - Updated and secured (ID: exists)
|
||||
- [x] ✅ Git submodule integration and testing - Both submodules operational
|
||||
- [x] ✅ Create comprehensive submodule documentation - docs/submodule-workflow.md
|
||||
- [ ] Set up CI/CD pipeline with Gitea Actions (P1) - Next priority
|
||||
- [ ] Implement Docker security hardening (P1) - Next priority
|
||||
|
||||
### 📋 Medium Priority
|
||||
- [ ] Add production/staging inventory configurations
|
||||
@@ -79,7 +85,7 @@
|
||||
## Known Issues
|
||||
|
||||
1. **derp VM stopped** - Requires ansible user creation, deferred (low priority)
|
||||
2. **Git push blocked** - Gitea server pre-receive hook permission issue
|
||||
2. ~~**Git push blocked**~~ - ✅ RESOLVED - SSH key created, repository recreated
|
||||
3. **pihole LVM missing** - Non-compliant with CLAUDE.md, migration needed
|
||||
4. ~~**QEMU agent channels**~~ - ✅ RESOLVED - mymx QEMU agent verified operational
|
||||
5. **Molecule tests** - Structure exists but not functional
|
||||
@@ -93,6 +99,13 @@
|
||||
## Quick Wins (< 30 min each)
|
||||
|
||||
- [x] ✅ Execute install_qemu_agent.yml on mymx
|
||||
- [x] ✅ Create SSH key for git operations (secrets/ssh/ansible)
|
||||
- [x] ✅ Configure git to use SSH key authentication
|
||||
- [x] ✅ Recreate Gitea repository with proper permissions
|
||||
- [x] ✅ Separate inventories into dedicated repository (PRIVATE)
|
||||
- [x] ✅ Separate secrets into dedicated repository (PRIVATE)
|
||||
- [x] ✅ Configure git submodules for inventories and secrets
|
||||
- [x] ✅ Create submodule workflow documentation
|
||||
- [ ] Fix inventory group name sanitization
|
||||
- [x] ✅ Add audit_docker.yml playbook
|
||||
- [ ] Create testing cheatsheet
|
||||
|
||||
122
docs/git-ssh-setup.md
Normal file
122
docs/git-ssh-setup.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Git SSH Key Setup for Gitea
|
||||
|
||||
## Overview
|
||||
|
||||
Git is now configured to use SSH key authentication for all operations with `git.mymx.me`.
|
||||
|
||||
## SSH Key Details
|
||||
|
||||
- **Location**: `/opt/ansible/secrets/ssh/ansible`
|
||||
- **Type**: ed25519
|
||||
- **Fingerprint**: `SHA256:mkgq5V567C/CJas9nbP16kNzzVqs7z7k2X90qdP0QXE`
|
||||
- **User**: `ansible@mymx.me`
|
||||
- **Passphrase**: Stored in `secrets/ssh/README.md`
|
||||
|
||||
## Configuration
|
||||
|
||||
### Git Configuration
|
||||
|
||||
Git has been configured to use the SSH key:
|
||||
|
||||
```bash
|
||||
git config core.sshCommand "ssh -i /opt/ansible/secrets/ssh/ansible"
|
||||
```
|
||||
|
||||
### SSH Agent Initialization
|
||||
|
||||
An automatic SSH agent initialization script has been created at `/opt/ansible/.ssh-agent-init`.
|
||||
|
||||
To use in new shells, add to your shell profile:
|
||||
|
||||
```bash
|
||||
source /opt/ansible/.ssh-agent-init
|
||||
```
|
||||
|
||||
This script will:
|
||||
1. Start ssh-agent if not running
|
||||
2. Load the ansible SSH key with passphrase automatically
|
||||
3. Persist the agent across shell sessions
|
||||
|
||||
## Usage
|
||||
|
||||
### Current Shell
|
||||
|
||||
In your current shell, source the initialization script:
|
||||
|
||||
```bash
|
||||
source /opt/ansible/.ssh-agent-init
|
||||
```
|
||||
|
||||
### Git Operations
|
||||
|
||||
All standard git operations now work with SSH authentication:
|
||||
|
||||
```bash
|
||||
# Fetch updates
|
||||
git fetch origin
|
||||
|
||||
# Pull changes
|
||||
git pull origin master
|
||||
|
||||
# Push commits
|
||||
git push origin master
|
||||
|
||||
# Check remote
|
||||
git ls-remote origin
|
||||
```
|
||||
|
||||
### Manual SSH Key Management
|
||||
|
||||
If you need to manually manage the SSH key:
|
||||
|
||||
```bash
|
||||
# Check loaded keys
|
||||
ssh-add -l
|
||||
|
||||
# Add key manually (will prompt for passphrase)
|
||||
ssh-add /opt/ansible/secrets/ssh/ansible
|
||||
|
||||
# Remove key from agent
|
||||
ssh-add -d /opt/ansible/secrets/ssh/ansible
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Could not open a connection to your authentication agent"
|
||||
|
||||
Run the initialization script:
|
||||
|
||||
```bash
|
||||
source /opt/ansible/.ssh-agent-init
|
||||
```
|
||||
|
||||
### "Permission denied (publickey)"
|
||||
|
||||
Ensure the key is loaded in ssh-agent:
|
||||
|
||||
```bash
|
||||
ssh-add -l
|
||||
```
|
||||
|
||||
If not listed, source the initialization script or add manually.
|
||||
|
||||
### Verify SSH Connection
|
||||
|
||||
Test SSH connection to Gitea:
|
||||
|
||||
```bash
|
||||
ssh -T git@git.mymx.me -p 2222 -i /opt/ansible/secrets/ssh/ansible
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Private key is stored in `secrets/` directory (should be in separate git repository)
|
||||
- Passphrase is documented in `secrets/ssh/README.md`
|
||||
- SSH key has read/write access to ansible repositories on git.mymx.me
|
||||
- Key was uploaded to Gitea with Key ID: 5
|
||||
|
||||
## References
|
||||
|
||||
- Passphrase details: `secrets/ssh/README.md`
|
||||
- SSH config: `~/.ssh/config`
|
||||
- Git config: `.git/config` (core.sshCommand)
|
||||
400
docs/submodule-workflow.md
Normal file
400
docs/submodule-workflow.md
Normal file
@@ -0,0 +1,400 @@
|
||||
# Git Submodule Workflow
|
||||
|
||||
This repository uses git submodules to separate concerns and follow CLAUDE.md guidelines.
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
infra-automation/ # Main repository (PUBLIC)
|
||||
├── inventories/ # → ansible-inventories submodule (PUBLIC)
|
||||
├── secrets/ # → secrets submodule (PRIVATE)
|
||||
├── playbooks/
|
||||
├── roles/
|
||||
└── docs/
|
||||
```
|
||||
|
||||
## Submodules
|
||||
|
||||
### 1. inventories (PRIVATE)
|
||||
- **URL:** `ssh://git@git.mymx.me:2222/ansible/ansible-inventories.git`
|
||||
- **Type:** PRIVATE repository
|
||||
- **Contents:** Dynamic inventories, host/group variables (may contain internal IPs/hostnames)
|
||||
- **Purpose:** Separate inventory management from infrastructure code, protect internal network topology
|
||||
|
||||
### 2. secrets (PRIVATE)
|
||||
- **URL:** `ssh://git@git.mymx.me:2222/ansible/secrets.git`
|
||||
- **Type:** PRIVATE repository
|
||||
- **Contents:** SSH keys, vault files, sensitive data
|
||||
- **Purpose:** Security isolation, separate access control
|
||||
|
||||
## Initial Clone
|
||||
|
||||
### Option 1: Clone with submodules (recommended)
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
cd infra-automation
|
||||
```
|
||||
|
||||
### Option 2: Clone then initialize submodules
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
cd infra-automation
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
## Working with Submodules
|
||||
|
||||
### Update All Submodules
|
||||
|
||||
```bash
|
||||
# Update to latest commits from remote
|
||||
git submodule update --remote
|
||||
|
||||
# Commit submodule updates in main repository
|
||||
git add inventories secrets
|
||||
git commit -m "Update submodule references"
|
||||
git push
|
||||
```
|
||||
|
||||
### Update Specific Submodule
|
||||
|
||||
```bash
|
||||
# Update only inventories
|
||||
git submodule update --remote inventories
|
||||
|
||||
# Update only secrets
|
||||
git submodule update --remote secrets
|
||||
```
|
||||
|
||||
### Making Changes in Submodules
|
||||
|
||||
#### Method 1: Work inside submodule
|
||||
|
||||
```bash
|
||||
# Navigate to submodule
|
||||
cd inventories
|
||||
|
||||
# Ensure on correct branch
|
||||
git checkout master
|
||||
|
||||
# Make changes
|
||||
vim production/libvirt.yml
|
||||
|
||||
# Commit and push from submodule
|
||||
git add production/libvirt.yml
|
||||
git commit -m "Update libvirt inventory configuration"
|
||||
git push origin master
|
||||
|
||||
# Update parent repository reference
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Update inventories submodule"
|
||||
git push
|
||||
```
|
||||
|
||||
#### Method 2: Direct submodule update
|
||||
|
||||
```bash
|
||||
# Make changes, commit, and push in one workflow
|
||||
cd inventories
|
||||
git pull origin master
|
||||
# Make changes
|
||||
git add .
|
||||
git commit -m "Changes"
|
||||
git push origin master
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Update inventories"
|
||||
git push
|
||||
```
|
||||
|
||||
### Checking Submodule Status
|
||||
|
||||
```bash
|
||||
# View submodule status
|
||||
git submodule status
|
||||
|
||||
# View detailed info
|
||||
git submodule
|
||||
|
||||
# Check for uncommitted changes in submodules
|
||||
git submodule foreach git status
|
||||
```
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Workflow 1: Update Inventory Configuration
|
||||
|
||||
```bash
|
||||
# 1. Navigate to inventories
|
||||
cd inventories
|
||||
|
||||
# 2. Pull latest changes
|
||||
git pull origin master
|
||||
|
||||
# 3. Make changes
|
||||
vim production/group_vars/all.yml
|
||||
|
||||
# 4. Commit and push
|
||||
git add production/group_vars/all.yml
|
||||
git commit -m "Update production variables"
|
||||
git push origin master
|
||||
|
||||
# 5. Update parent repository
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Update inventories submodule reference"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### Workflow 2: Add New SSH Key to Secrets
|
||||
|
||||
```bash
|
||||
# 1. Navigate to secrets
|
||||
cd secrets
|
||||
|
||||
# 2. Pull latest (important for private repo)
|
||||
git pull origin master
|
||||
|
||||
# 3. Add new key
|
||||
ssh-keygen -t ed25519 -f ssh/newkey -C "description"
|
||||
|
||||
# 4. Document in README
|
||||
vim ssh/README.md
|
||||
|
||||
# 5. Commit and push
|
||||
git add ssh/
|
||||
git commit -m "Add new SSH key: newkey"
|
||||
git push origin master
|
||||
|
||||
# 6. Update parent
|
||||
cd ..
|
||||
git add secrets
|
||||
git commit -m "Update secrets submodule"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### Workflow 3: Clone Project on New Machine
|
||||
|
||||
```bash
|
||||
# 1. Clone with submodules
|
||||
git clone --recurse-submodules ssh://git@git.mymx.me:2222/ansible/infra-automation.git
|
||||
cd infra-automation
|
||||
|
||||
# 2. Verify submodules initialized
|
||||
git submodule status
|
||||
# Should show: ebe29b6... inventories (heads/master)
|
||||
# 8def011... secrets (heads/master)
|
||||
|
||||
# 3. Set up SSH agent for git operations
|
||||
source .ssh-agent-init
|
||||
|
||||
# 4. Verify inventory works
|
||||
ansible-inventory -i inventories/production/libvirt.yml --list
|
||||
|
||||
# 5. Ready to use!
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Submodule Not Initialized
|
||||
|
||||
**Problem:** Submodule directory exists but is empty
|
||||
|
||||
```bash
|
||||
# Solution
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
### Submodule Detached HEAD
|
||||
|
||||
**Problem:** Submodule is in detached HEAD state
|
||||
|
||||
```bash
|
||||
# Solution: checkout master branch
|
||||
cd submodule_name
|
||||
git checkout master
|
||||
git pull origin master
|
||||
cd ..
|
||||
git add submodule_name
|
||||
git commit -m "Update submodule to track master"
|
||||
```
|
||||
|
||||
### Submodule Changes Not Showing
|
||||
|
||||
**Problem:** Made changes in submodule but parent doesn't show update
|
||||
|
||||
```bash
|
||||
# Solution: Stage submodule in parent
|
||||
git add submodule_name
|
||||
git commit -m "Update submodule reference"
|
||||
```
|
||||
|
||||
### Permission Denied on Private Submodule
|
||||
|
||||
**Problem:** Cannot clone/update secrets submodule
|
||||
|
||||
```bash
|
||||
# Solution: Ensure SSH key is loaded
|
||||
source /opt/ansible/.ssh-agent-init
|
||||
ssh-add -l
|
||||
|
||||
# Verify access
|
||||
ssh -T git@git.mymx.me -p 2222
|
||||
|
||||
# Try update again
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
### Accidentally Committed Changes to Detached HEAD
|
||||
|
||||
**Problem:** Made commits in submodule while in detached HEAD
|
||||
|
||||
```bash
|
||||
# Solution: Create branch from detached commits
|
||||
cd submodule_name
|
||||
git branch temp-branch
|
||||
git checkout master
|
||||
git merge temp-branch
|
||||
git push origin master
|
||||
git branch -d temp-branch
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always Work on Branches
|
||||
```bash
|
||||
cd inventories
|
||||
git checkout master
|
||||
# Never work in detached HEAD
|
||||
```
|
||||
|
||||
### 2. Pull Before Push
|
||||
```bash
|
||||
cd secrets
|
||||
git pull origin master
|
||||
# Make changes
|
||||
git push origin master
|
||||
```
|
||||
|
||||
### 3. Update Parent After Submodule Changes
|
||||
```bash
|
||||
# After pushing submodule changes
|
||||
cd ..
|
||||
git add submodule_name
|
||||
git commit -m "Update submodule"
|
||||
git push
|
||||
```
|
||||
|
||||
### 4. Regular Submodule Updates
|
||||
```bash
|
||||
# Weekly: update all submodules
|
||||
git submodule update --remote
|
||||
git add inventories secrets
|
||||
git commit -m "Update submodules to latest"
|
||||
git push
|
||||
```
|
||||
|
||||
### 5. Document Submodule Changes
|
||||
```bash
|
||||
# Use descriptive commit messages
|
||||
git commit -m "Update inventories: Add staging environment configuration"
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Secrets Submodule (PRIVATE)
|
||||
- ⚠️ Never make secrets repository public
|
||||
- ⚠️ Verify .gitignore before committing
|
||||
- ⚠️ Use SSH key authentication only
|
||||
- ⚠️ Regular access audits
|
||||
- ⚠️ Rotate keys according to schedule
|
||||
|
||||
### Inventories Submodule (PRIVATE)
|
||||
- ⚠️ Private repository - protects network topology
|
||||
- ⚠️ Contains internal IPs, hostnames, network structure
|
||||
- ✅ Use vault references for passwords/secrets
|
||||
- ✅ Document all group/host variables
|
||||
- ✅ Controlled team access only
|
||||
|
||||
## Advanced Operations
|
||||
|
||||
### Reset Submodule to Specific Commit
|
||||
|
||||
```bash
|
||||
cd inventories
|
||||
git checkout <commit-hash>
|
||||
cd ..
|
||||
git add inventories
|
||||
git commit -m "Pin inventories to specific version"
|
||||
```
|
||||
|
||||
### Remove Submodule
|
||||
|
||||
```bash
|
||||
# 1. Deinitialize
|
||||
git submodule deinit -f inventories
|
||||
|
||||
# 2. Remove from git
|
||||
git rm -f inventories
|
||||
|
||||
# 3. Remove module directory
|
||||
rm -rf .git/modules/inventories
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "Remove inventories submodule"
|
||||
```
|
||||
|
||||
### Change Submodule URL
|
||||
|
||||
```bash
|
||||
# Update .gitmodules
|
||||
git config --file=.gitmodules submodule.inventories.url <new-url>
|
||||
|
||||
# Sync
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Commit
|
||||
git add .gitmodules
|
||||
git commit -m "Update submodule URL"
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Action | Command |
|
||||
|--------|---------|
|
||||
| Clone with submodules | `git clone --recurse-submodules <url>` |
|
||||
| Init submodules | `git submodule init` |
|
||||
| Update submodules | `git submodule update` |
|
||||
| Update to latest | `git submodule update --remote` |
|
||||
| Check status | `git submodule status` |
|
||||
| Foreach command | `git submodule foreach <command>` |
|
||||
| Work in submodule | `cd submodule && git checkout master` |
|
||||
| Update parent reference | `git add submodule && git commit` |
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Git SSH Setup](git-ssh-setup.md) - SSH key configuration
|
||||
- [CLAUDE.md](../CLAUDE.md) - Repository structure guidelines
|
||||
- [ansible-inventories README](https://git.mymx.me/ansible/ansible-inventories) - Inventory documentation
|
||||
- [secrets README](https://git.mymx.me/ansible/secrets) - Secrets management (PRIVATE)
|
||||
|
||||
## Compliance
|
||||
|
||||
This submodule structure follows CLAUDE.md requirements with security enhancements:
|
||||
- ✅ `./inventories` in PRIVATE repository (protects network topology)
|
||||
- ✅ `./secrets` in PRIVATE repository (protects sensitive data)
|
||||
- ✅ Separation of concerns
|
||||
- ✅ Independent version control
|
||||
- ✅ Proper access controls
|
||||
- ✅ Network topology protection
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-11-11
|
||||
**Workflow Version:** 1.0
|
||||
1
inventories
Submodule
1
inventories
Submodule
Submodule inventories added at dba3d7b922
@@ -1,87 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Global Variables for All Hosts
|
||||
# =============================================================================
|
||||
# Applied to all hosts in the development inventory
|
||||
# =============================================================================
|
||||
|
||||
# Ansible Connection Settings
|
||||
# -----------------------------------------------------------------------------
|
||||
ansible_connection: ssh
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
|
||||
# SSH Connection Optimization
|
||||
ansible_ssh_pipelining: true
|
||||
ansible_ssh_retries: 3
|
||||
|
||||
# Privilege Escalation
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
ansible_become_user: root
|
||||
|
||||
# Fact Gathering
|
||||
gather_subset:
|
||||
- '!all'
|
||||
- '!min'
|
||||
- network
|
||||
- hardware
|
||||
- virtual
|
||||
|
||||
# Environment
|
||||
# -----------------------------------------------------------------------------
|
||||
environment: development
|
||||
environment_name: development # Deprecated - use 'environment'
|
||||
deployment_timestamp: "{{ ansible_date_time.iso8601 }}"
|
||||
|
||||
# Security Settings
|
||||
# -----------------------------------------------------------------------------
|
||||
security_hardening_enabled: false # Less strict for dev environment
|
||||
selinux_enabled: true
|
||||
selinux_mode: permissive # Permissive for development
|
||||
firewall_enabled: true
|
||||
|
||||
# System Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
timezone: "UTC"
|
||||
ntp_servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
- 2.pool.ntp.org
|
||||
|
||||
# Package Management
|
||||
# -----------------------------------------------------------------------------
|
||||
package_state: present
|
||||
enable_automatic_updates: false # Manual control in dev
|
||||
|
||||
# Monitoring & Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
log_rotation_enabled: true
|
||||
log_retention_days: 30
|
||||
syslog_server: null # No central logging in dev
|
||||
|
||||
# Essential Packages (from CLAUDE.md)
|
||||
# -----------------------------------------------------------------------------
|
||||
essential_packages:
|
||||
- vim
|
||||
- htop
|
||||
- tmux
|
||||
- jq
|
||||
- bc
|
||||
- curl
|
||||
- wget
|
||||
- rsync
|
||||
- git
|
||||
- python3
|
||||
- python3-pip
|
||||
|
||||
# Security Packages (from CLAUDE.md)
|
||||
# -----------------------------------------------------------------------------
|
||||
security_packages:
|
||||
- aide
|
||||
- auditd
|
||||
|
||||
# Development Flags
|
||||
# -----------------------------------------------------------------------------
|
||||
dev_mode: true
|
||||
debug_enabled: false
|
||||
verbose_logging: false
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Development Environment - Encrypted Secrets (EXAMPLE)
|
||||
# =============================================================================
|
||||
#
|
||||
# This is an EXAMPLE vault file. To use:
|
||||
#
|
||||
# 1. Copy this file to vault.yml:
|
||||
# cp vault.yml.example vault.yml
|
||||
#
|
||||
# 2. Fill in actual values (can use simple passwords for dev)
|
||||
#
|
||||
# 3. Encrypt with ansible-vault:
|
||||
# ansible-vault encrypt inventories/development/group_vars/all/vault.yml
|
||||
#
|
||||
# NOTE: Development environment can use simpler credentials
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# User Credentials
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_ansible_user_ssh_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ... ansible@example.com"
|
||||
vault_root_password: "dev_root_password"
|
||||
vault_ansible_become_password: "dev_sudo_password"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# API Tokens (Development)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_aws_access_key_id: "dev_aws_access_key"
|
||||
vault_aws_secret_access_key: "dev_aws_secret_key"
|
||||
|
||||
vault_gitea_username: "ansible@mymx.me"
|
||||
vault_gitea_password: "79,;,metOND"
|
||||
|
||||
vault_mailcow_username: "ansible@mymx.me"
|
||||
vault_mailcow_password: "79,;,metOND"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Database Credentials (Development)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_mysql_root_password: "dev_mysql_root"
|
||||
vault_postgresql_postgres_password: "dev_postgres"
|
||||
vault_mongodb_admin_password: "dev_mongo"
|
||||
vault_redis_password: "dev_redis"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Application Secrets (Development)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_app_secret_key: "dev_app_secret_key_changeme"
|
||||
vault_app_api_key: "dev_api_key"
|
||||
@@ -1,84 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Hypervisors Group Variables
|
||||
# =============================================================================
|
||||
# Configuration for KVM/QEMU hypervisor hosts
|
||||
# =============================================================================
|
||||
|
||||
# Virtualization Platform
|
||||
# -----------------------------------------------------------------------------
|
||||
virtualization_type: kvm
|
||||
virtualization_role: host
|
||||
hypervisor_vendor: qemu
|
||||
libvirt_version: "11.3.0"
|
||||
qemu_version: "8.0+"
|
||||
|
||||
# Libvirt Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
libvirt_uri: "qemu:///system"
|
||||
libvirt_socket: "/var/run/libvirt/libvirt-sock"
|
||||
libvirt_daemon_enabled: true
|
||||
libvirt_autostart: true
|
||||
|
||||
# Network Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
libvirt_networks:
|
||||
- name: default
|
||||
bridge: virbr0
|
||||
subnet: "192.168.122.0/24"
|
||||
dhcp_enabled: true
|
||||
dhcp_range_start: "192.168.122.2"
|
||||
dhcp_range_end: "192.168.122.254"
|
||||
autostart: true
|
||||
|
||||
# Storage Pools
|
||||
# -----------------------------------------------------------------------------
|
||||
libvirt_storage_pools:
|
||||
- name: default
|
||||
type: dir
|
||||
path: /var/lib/libvirt/images
|
||||
autostart: true
|
||||
|
||||
# VM Management
|
||||
# -----------------------------------------------------------------------------
|
||||
vm_management_tool: virsh
|
||||
vm_console_access: true
|
||||
vm_serial_console_enabled: true
|
||||
|
||||
# SSH Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
ansible_ssh_extra_args: '-o ForwardAgent=yes'
|
||||
|
||||
# Resource Allocation
|
||||
# -----------------------------------------------------------------------------
|
||||
max_vms: 10
|
||||
cpu_overcommit_ratio: 2
|
||||
memory_overcommit_ratio: 1.5
|
||||
|
||||
# Monitoring
|
||||
# -----------------------------------------------------------------------------
|
||||
monitor_vm_performance: true
|
||||
monitor_host_resources: true
|
||||
alert_on_high_load: true
|
||||
|
||||
# Security
|
||||
# -----------------------------------------------------------------------------
|
||||
selinux_enabled: true
|
||||
selinux_mode: enforcing
|
||||
firewalld_enabled: true
|
||||
firewalld_default_zone: public
|
||||
|
||||
# Required Hypervisor Packages
|
||||
# -----------------------------------------------------------------------------
|
||||
hypervisor_packages:
|
||||
- qemu-kvm
|
||||
- libvirt-daemon
|
||||
- libvirt-daemon-system
|
||||
- libvirt-clients
|
||||
- bridge-utils
|
||||
- virt-manager
|
||||
- virt-viewer
|
||||
- guestfs-tools
|
||||
- libguestfs-tools
|
||||
- python3-libvirt
|
||||
- virtinst
|
||||
@@ -1,101 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# KVM Guest VMs Group Variables
|
||||
# =============================================================================
|
||||
# Common configuration for all KVM guest virtual machines
|
||||
# =============================================================================
|
||||
|
||||
# VM Platform Details
|
||||
# -----------------------------------------------------------------------------
|
||||
virtualization_type: kvm
|
||||
virtualization_role: guest
|
||||
hypervisor_host: grokbox
|
||||
management_interface: libvirt
|
||||
|
||||
# Network Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
vm_network_type: nat
|
||||
vm_network_bridge: virbr0
|
||||
vm_network_subnet: "192.168.122.0/24"
|
||||
vm_gateway: "192.168.122.1"
|
||||
|
||||
# SSH & Connectivity
|
||||
# -----------------------------------------------------------------------------
|
||||
# Force SSH connection (override libvirt_qemu from dynamic inventory)
|
||||
ansible_connection: ssh
|
||||
ansible_user: ansible
|
||||
ansible_become_password: null # Passwordless sudo configured
|
||||
|
||||
# Connection via ProxyJump through hypervisor
|
||||
ansible_ssh_common_args: >-
|
||||
-o ProxyJump=grokbox
|
||||
-o StrictHostKeyChecking=accept-new
|
||||
-o ServerAliveInterval=45
|
||||
-o ServerAliveCountMax=3
|
||||
-o ControlMaster=auto
|
||||
-o ControlPersist=600s
|
||||
|
||||
# Storage Configuration (LVM - per CLAUDE.md)
|
||||
# -----------------------------------------------------------------------------
|
||||
lvm_enabled: true
|
||||
lvm_vg_name: vg_system
|
||||
lvm_pvs:
|
||||
- /dev/vda2
|
||||
|
||||
lvm_lvs:
|
||||
- name: lv_root
|
||||
size: 8G
|
||||
mount_point: /
|
||||
fstype: ext4
|
||||
- name: lv_boot
|
||||
size: 2G
|
||||
mount_point: /boot
|
||||
fstype: ext4
|
||||
- name: lv_opt
|
||||
size: 3G
|
||||
mount_point: /opt
|
||||
fstype: ext4
|
||||
- name: lv_tmp
|
||||
size: 1G
|
||||
mount_point: /tmp
|
||||
fstype: ext4
|
||||
mount_options: noexec,nosuid,nodev
|
||||
- name: lv_home
|
||||
size: 2G
|
||||
mount_point: /home
|
||||
fstype: ext4
|
||||
- name: lv_var_log
|
||||
size: 2G
|
||||
mount_point: /var/log
|
||||
fstype: ext4
|
||||
- name: lv_var_audit
|
||||
size: 1G
|
||||
mount_point: /var/log/audit
|
||||
fstype: ext4
|
||||
- name: lv_swap
|
||||
size: 1G
|
||||
fstype: swap
|
||||
|
||||
# Resource Monitoring Thresholds
|
||||
# -----------------------------------------------------------------------------
|
||||
disk_usage_warning_threshold: 80
|
||||
disk_usage_critical_threshold: 90
|
||||
memory_warning_threshold: 85
|
||||
memory_critical_threshold: 95
|
||||
cpu_warning_threshold: 80
|
||||
|
||||
# Backup Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
backup_enabled: false # Development environment
|
||||
snapshot_enabled: true
|
||||
snapshot_retention_days: 7
|
||||
|
||||
# VM Lifecycle
|
||||
# -----------------------------------------------------------------------------
|
||||
vm_autostart: true
|
||||
vm_shutdown_timeout: 300 # seconds
|
||||
|
||||
# Cloud-init Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
cloud_init_enabled: true
|
||||
cloud_init_datasource: NoCloud
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
# Override libvirt connection with SSH
|
||||
ansible_connection: ssh
|
||||
ansible_host: 192.168.122.99
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
# Override libvirt connection with SSH
|
||||
ansible_connection: ssh
|
||||
ansible_host: 192.168.122.119
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
# Override libvirt connection with SSH
|
||||
ansible_connection: ssh
|
||||
ansible_host: 192.168.122.12
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Libvirt/KVM Dynamic Inventory Configuration
|
||||
# =============================================================================
|
||||
# Configuration for community.libvirt.libvirt dynamic inventory plugin
|
||||
# Documentation: ansible-doc -t inventory community.libvirt.libvirt
|
||||
# =============================================================================
|
||||
|
||||
plugin: community.libvirt.libvirt
|
||||
|
||||
# Hypervisor Connection
|
||||
# -----------------------------------------------------------------------------
|
||||
# URI to connect to libvirt hypervisor
|
||||
# Remote SSH connection to grokbox hypervisor
|
||||
uri: 'qemu+ssh://grok@grok.home.serneels.xyz/system'
|
||||
|
||||
# Inventory Hostname Format
|
||||
# -----------------------------------------------------------------------------
|
||||
# How to register VMs as inventory hostnames
|
||||
# Options: 'name' (use VM name) or 'uuid' (use UUID)
|
||||
inventory_hostname: name
|
||||
|
||||
# Grouping Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
# Automatically create groups based on VM characteristics
|
||||
compose:
|
||||
# Extract IP address from guest_info interface data
|
||||
ansible_host: >-
|
||||
guest_info['if.1.addr.0.addr'] if 'if.1.addr.0.addr' in guest_info else
|
||||
(guest_info['if.0.addr.0.addr'] if 'if.0.addr.0.addr' in guest_info and guest_info['if.0.addr.0.addr'] != '127.0.0.1' else omit)
|
||||
|
||||
groups:
|
||||
# Group by VM state (from info dict)
|
||||
running_vms: info.state == 'running'
|
||||
stopped_vms: info.state != 'running'
|
||||
|
||||
# Group by resource allocation (convert KB to MB)
|
||||
small_vms: (info.memory_kb | int / 1024) <= 2048
|
||||
medium_vms: (info.memory_kb | int / 1024) > 2048 and (info.memory_kb | int / 1024) <= 8192
|
||||
large_vms: (info.memory_kb | int / 1024) > 8192
|
||||
|
||||
# Group all discovered VMs as kvm_guests
|
||||
kvm_guests: true
|
||||
|
||||
# Keyed Groups
|
||||
# -----------------------------------------------------------------------------
|
||||
# Create dynamic groups based on host variables
|
||||
keyed_groups:
|
||||
- key: info.state
|
||||
prefix: state
|
||||
separator: "_"
|
||||
|
||||
- key: guest_info['os.id'] | default('unknown')
|
||||
prefix: os
|
||||
separator: "_"
|
||||
|
||||
# Filters
|
||||
# -----------------------------------------------------------------------------
|
||||
# Set strict mode for error handling
|
||||
strict: false
|
||||
@@ -1,97 +0,0 @@
|
||||
# Production Inventory
|
||||
|
||||
This directory contains dynamic inventory configurations for the production environment.
|
||||
|
||||
## Available Inventory Sources
|
||||
|
||||
### 1. Libvirt/KVM Dynamic Inventory (Active)
|
||||
|
||||
**File**: `libvirt_kvm.yml`
|
||||
|
||||
Uses custom libvirt plugin to discover VMs on production hypervisors.
|
||||
|
||||
```bash
|
||||
# List all production hosts
|
||||
ansible-inventory -i inventories/production/libvirt_kvm.yml --list
|
||||
|
||||
# Test connectivity
|
||||
ansible all -i inventories/production/libvirt_kvm.yml -m ping
|
||||
```
|
||||
|
||||
### 2. NetBox CMDB (Example Configuration)
|
||||
|
||||
**File**: `netbox.yml.example`
|
||||
|
||||
For NetBox-based infrastructure management:
|
||||
|
||||
1. Rename `netbox.yml.example` to `netbox.yml`
|
||||
2. Configure NetBox API endpoint and token
|
||||
3. Install required collection:
|
||||
```bash
|
||||
ansible-galaxy collection install netbox.netbox
|
||||
```
|
||||
|
||||
### 3. AWS EC2 (Example Configuration)
|
||||
|
||||
**File**: `aws_ec2.yml.example`
|
||||
|
||||
For AWS cloud infrastructure:
|
||||
|
||||
1. Rename `aws_ec2.yml.example` to `aws_ec2.yml`
|
||||
2. Configure AWS regions and filters
|
||||
3. Install required collection:
|
||||
```bash
|
||||
ansible-galaxy collection install amazon.aws
|
||||
pip3 install boto3 botocore
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Group Variables
|
||||
|
||||
Add production-specific variables in:
|
||||
- `group_vars/all.yml` - Global production settings
|
||||
- `group_vars/all/vault.yml` - Encrypted secrets
|
||||
- `group_vars/webservers.yml` - Web server group settings
|
||||
- `group_vars/databases.yml` - Database group settings
|
||||
|
||||
### Host Variables
|
||||
|
||||
Add host-specific variables in:
|
||||
- `host_vars/<hostname>.yml`
|
||||
|
||||
## Security
|
||||
|
||||
- All secrets must be encrypted using Ansible Vault
|
||||
- Never commit plaintext credentials
|
||||
- Use environment variables or external secret managers when possible
|
||||
- Rotate credentials every 90 days
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Run against all production hosts
|
||||
ansible-playbook -i inventories/production site.yml
|
||||
|
||||
# Run against specific group
|
||||
ansible-playbook -i inventories/production site.yml --limit webservers
|
||||
|
||||
# Check mode (dry-run)
|
||||
ansible-playbook -i inventories/production site.yml --check
|
||||
|
||||
# With specific tags
|
||||
ansible-playbook -i inventories/production site.yml --tags security
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
# Validate inventory syntax
|
||||
ansible-inventory -i inventories/production --list
|
||||
|
||||
# Check specific host
|
||||
ansible-inventory -i inventories/production --host hostname
|
||||
|
||||
# Graph inventory structure
|
||||
ansible-inventory -i inventories/production --graph
|
||||
```
|
||||
@@ -1,93 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Production Environment - AWS EC2 Dynamic Inventory (EXAMPLE)
|
||||
# =============================================================================
|
||||
#
|
||||
# This is an example configuration for AWS EC2 dynamic inventory.
|
||||
# Rename to aws_ec2.yml and configure with your AWS details.
|
||||
#
|
||||
# Requirements:
|
||||
# ansible-galaxy collection install amazon.aws
|
||||
# pip3 install boto3 botocore
|
||||
#
|
||||
# Authentication:
|
||||
# - AWS credentials via ~/.aws/credentials
|
||||
# - IAM role (recommended for EC2 control nodes)
|
||||
# - Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
|
||||
#
|
||||
# Usage:
|
||||
# ansible-inventory -i inventories/production/aws_ec2.yml --list
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
plugin: amazon.aws.aws_ec2
|
||||
|
||||
# AWS Regions to query
|
||||
regions:
|
||||
- us-east-1
|
||||
- us-west-2
|
||||
# - eu-west-1
|
||||
# - ap-southeast-1
|
||||
|
||||
# Instance filters
|
||||
filters:
|
||||
tag:Environment: production
|
||||
instance-state-name: running
|
||||
|
||||
# Use private IP for internal networks, public for external
|
||||
hostnames:
|
||||
- tag:Name
|
||||
- dns-name
|
||||
- private-ip-address
|
||||
|
||||
# Compose variables
|
||||
compose:
|
||||
ansible_host: private_ip_address
|
||||
# For public access:
|
||||
# ansible_host: public_ip_address
|
||||
|
||||
environment: production
|
||||
aws_region: placement.region
|
||||
aws_az: placement.availability_zone
|
||||
instance_type: instance_type
|
||||
vpc_id: vpc_id
|
||||
|
||||
# Keyed groups
|
||||
keyed_groups:
|
||||
# Group by tag:Role
|
||||
- key: tags.Role
|
||||
prefix: role
|
||||
separator: "_"
|
||||
|
||||
# Group by tag:Service
|
||||
- key: tags.Service
|
||||
prefix: service
|
||||
separator: "_"
|
||||
|
||||
# Group by instance type
|
||||
- key: instance_type
|
||||
prefix: instance_type
|
||||
|
||||
# Group by availability zone
|
||||
- key: placement.availability_zone
|
||||
prefix: az
|
||||
|
||||
# Group by VPC
|
||||
- key: vpc_id
|
||||
prefix: vpc
|
||||
|
||||
# Strict mode (fail if groups can't be created)
|
||||
strict: false
|
||||
|
||||
# Cache settings
|
||||
cache: true
|
||||
cache_plugin: jsonfile
|
||||
cache_timeout: 3600
|
||||
cache_connection: /tmp/ansible_aws_inventory_cache
|
||||
cache_prefix: aws_ec2
|
||||
|
||||
# Include/exclude patterns
|
||||
# include_filters:
|
||||
# - tag:Managed: ansible
|
||||
# exclude_filters:
|
||||
# - tag:Backup: only
|
||||
@@ -1,176 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Production Environment - Global Variables
|
||||
# =============================================================================
|
||||
|
||||
# Environment designation
|
||||
environment: production
|
||||
|
||||
# Ansible connection settings
|
||||
ansible_user: ansible
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
|
||||
# SSH connection settings
|
||||
ansible_ssh_pipelining: true
|
||||
ansible_ssh_extra_args: '-o StrictHostKeyChecking=accept-new'
|
||||
|
||||
# =============================================================================
|
||||
# Network Configuration
|
||||
# =============================================================================
|
||||
|
||||
# NTP servers for time synchronization
|
||||
ntp_servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
- 2.pool.ntp.org
|
||||
- 3.pool.ntp.org
|
||||
|
||||
# DNS servers
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
- 1.1.1.1
|
||||
|
||||
# DNS search domains
|
||||
dns_search_domains:
|
||||
- example.com
|
||||
- production.local
|
||||
|
||||
# =============================================================================
|
||||
# Security Configuration
|
||||
# =============================================================================
|
||||
|
||||
# Automatic security updates
|
||||
security_auto_updates: true
|
||||
security_auto_reboot: false
|
||||
security_update_schedule: "daily"
|
||||
|
||||
# Firewall settings
|
||||
firewall_enabled: true
|
||||
firewall_default_policy: deny
|
||||
|
||||
# SELinux/AppArmor enforcement
|
||||
selinux_state: enforcing
|
||||
apparmor_enabled: true
|
||||
|
||||
# SSH hardening
|
||||
ssh_permit_root_login: no
|
||||
ssh_password_authentication: no
|
||||
ssh_gssapi_authentication: no
|
||||
ssh_max_auth_tries: 3
|
||||
ssh_client_alive_interval: 300
|
||||
|
||||
# Audit logging
|
||||
auditd_enabled: true
|
||||
auditd_log_retention_days: 365
|
||||
|
||||
# =============================================================================
|
||||
# Logging and Monitoring
|
||||
# =============================================================================
|
||||
|
||||
# Log retention
|
||||
log_retention_days: 365
|
||||
log_compression_enabled: true
|
||||
|
||||
# Syslog configuration
|
||||
syslog_remote_server: null # Set to remote syslog server if available
|
||||
syslog_remote_port: 514
|
||||
|
||||
# Monitoring
|
||||
monitoring_enabled: true
|
||||
monitoring_agent: null # Set to 'prometheus', 'zabbix', 'datadog', etc.
|
||||
|
||||
# =============================================================================
|
||||
# Backup Configuration
|
||||
# =============================================================================
|
||||
|
||||
backup_enabled: true
|
||||
backup_schedule: "0 2 * * *" # Daily at 2 AM
|
||||
backup_retention_days: 30
|
||||
backup_destination: /var/backups
|
||||
|
||||
# =============================================================================
|
||||
# Package Management
|
||||
# =============================================================================
|
||||
|
||||
# Essential packages (CLAUDE.md compliance)
|
||||
essential_packages:
|
||||
- vim
|
||||
- htop
|
||||
- tmux
|
||||
- jq
|
||||
- bc
|
||||
- curl
|
||||
- wget
|
||||
- rsync
|
||||
- git
|
||||
- python3
|
||||
- python3-pip
|
||||
|
||||
# Security packages
|
||||
security_packages:
|
||||
- aide
|
||||
- auditd
|
||||
- chrony
|
||||
|
||||
# Additional tools
|
||||
additional_packages:
|
||||
- net-tools
|
||||
- bind-utils # RHEL
|
||||
# - dnsutils # Debian (uncomment based on OS)
|
||||
- traceroute
|
||||
- tcpdump
|
||||
- strace
|
||||
- lsof
|
||||
|
||||
# =============================================================================
|
||||
# Performance Tuning
|
||||
# =============================================================================
|
||||
|
||||
# System limits
|
||||
system_max_open_files: 65535
|
||||
system_max_processes: 4096
|
||||
|
||||
# Kernel parameters (sysctl)
|
||||
kernel_parameters:
|
||||
net.ipv4.tcp_syncookies: 1
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.conf.default.rp_filter: 1
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
net.ipv4.conf.all.accept_source_route: 0
|
||||
net.ipv6.conf.all.accept_source_route: 0
|
||||
net.ipv4.conf.all.send_redirects: 0
|
||||
net.ipv4.conf.default.send_redirects: 0
|
||||
|
||||
# =============================================================================
|
||||
# Application Configuration
|
||||
# =============================================================================
|
||||
|
||||
# Default application user
|
||||
app_user: appuser
|
||||
app_group: appgroup
|
||||
|
||||
# Application directories
|
||||
app_base_dir: /opt/apps
|
||||
app_data_dir: /var/lib/apps
|
||||
app_log_dir: /var/log/apps
|
||||
|
||||
# =============================================================================
|
||||
# Compliance and Standards
|
||||
# =============================================================================
|
||||
|
||||
# Compliance frameworks
|
||||
compliance_frameworks:
|
||||
- CIS
|
||||
- NIST
|
||||
|
||||
# Configuration management
|
||||
config_management_tool: ansible
|
||||
config_management_version: "{{ ansible_version.full }}"
|
||||
|
||||
# =============================================================================
|
||||
# Custom Variables
|
||||
# =============================================================================
|
||||
|
||||
# Add production-specific custom variables here
|
||||
@@ -1,160 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Production Environment - Encrypted Secrets (EXAMPLE)
|
||||
# =============================================================================
|
||||
#
|
||||
# This is an EXAMPLE vault file. To use:
|
||||
#
|
||||
# 1. Copy this file to vault.yml:
|
||||
# cp vault.yml.example vault.yml
|
||||
#
|
||||
# 2. Fill in actual values (replace CHANGEME placeholders)
|
||||
#
|
||||
# 3. Encrypt with ansible-vault:
|
||||
# ansible-vault encrypt inventories/production/group_vars/all/vault.yml
|
||||
#
|
||||
# 4. Edit encrypted vault:
|
||||
# ansible-vault edit inventories/production/group_vars/all/vault.yml
|
||||
#
|
||||
# 5. Use in playbooks with --ask-vault-pass or --vault-password-file
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# User Credentials
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Ansible service account SSH key
|
||||
vault_ansible_user_ssh_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ... ansible@example.com"
|
||||
|
||||
# Root password for console access (if needed)
|
||||
vault_root_password: "CHANGEME_STRONG_PASSWORD"
|
||||
|
||||
# Ansible user sudo password (if passwordless sudo not configured)
|
||||
vault_ansible_become_password: "CHANGEME_SUDO_PASSWORD"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# API Tokens and Keys
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Cloud Provider API Tokens
|
||||
vault_aws_access_key_id: "CHANGEME_AWS_ACCESS_KEY"
|
||||
vault_aws_secret_access_key: "CHANGEME_AWS_SECRET_KEY"
|
||||
|
||||
vault_azure_subscription_id: "CHANGEME_AZURE_SUBSCRIPTION"
|
||||
vault_azure_client_id: "CHANGEME_AZURE_CLIENT_ID"
|
||||
vault_azure_secret: "CHANGEME_AZURE_SECRET"
|
||||
vault_azure_tenant: "CHANGEME_AZURE_TENANT"
|
||||
|
||||
vault_gcp_service_account_key: "CHANGEME_GCP_JSON_KEY"
|
||||
|
||||
vault_digitalocean_token: "CHANGEME_DO_TOKEN"
|
||||
|
||||
# CMDB API Tokens
|
||||
vault_netbox_api_token: "CHANGEME_NETBOX_TOKEN"
|
||||
vault_servicenow_api_token: "CHANGEME_SERVICENOW_TOKEN"
|
||||
|
||||
# Git/Repository Credentials
|
||||
vault_gitea_username: "ansible@mymx.me"
|
||||
vault_gitea_password: "79,;,metOND"
|
||||
vault_gitea_api_token: "CHANGEME_GITEA_TOKEN"
|
||||
|
||||
# Email Configuration
|
||||
vault_mailcow_username: "ansible@mymx.me"
|
||||
vault_mailcow_password: "79,;,metOND"
|
||||
vault_smtp_username: "ansible@mymx.me"
|
||||
vault_smtp_password: "79,;,metOND"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Database Credentials
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_mysql_root_password: "CHANGEME_MYSQL_ROOT"
|
||||
vault_mysql_replication_password: "CHANGEME_MYSQL_REPL"
|
||||
|
||||
vault_postgresql_postgres_password: "CHANGEME_PG_POSTGRES"
|
||||
vault_postgresql_replication_password: "CHANGEME_PG_REPL"
|
||||
|
||||
vault_mongodb_admin_password: "CHANGEME_MONGO_ADMIN"
|
||||
vault_redis_password: "CHANGEME_REDIS_PASSWORD"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Application Secrets
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_app_secret_key: "CHANGEME_APP_SECRET_32_CHARS_MIN"
|
||||
vault_app_api_key: "CHANGEME_APP_API_KEY"
|
||||
vault_app_jwt_secret: "CHANGEME_JWT_SECRET"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# SSL/TLS Certificates
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Private key for SSL certificates (PEM format)
|
||||
vault_ssl_private_key: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
CHANGEME_SSL_PRIVATE_KEY_CONTENT
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
# SSL certificate chain
|
||||
vault_ssl_certificate: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
CHANGEME_SSL_CERTIFICATE_CONTENT
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Certificate authority certificate
|
||||
vault_ssl_ca_certificate: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
CHANGEME_CA_CERTIFICATE_CONTENT
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Monitoring and Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_grafana_admin_password: "CHANGEME_GRAFANA_ADMIN"
|
||||
vault_prometheus_auth_token: "CHANGEME_PROMETHEUS_TOKEN"
|
||||
vault_zabbix_api_token: "CHANGEME_ZABBIX_TOKEN"
|
||||
vault_elasticsearch_password: "CHANGEME_ELASTIC_PASSWORD"
|
||||
vault_kibana_encryption_key: "CHANGEME_KIBANA_32_CHAR_KEY"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Backup and Recovery
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_backup_encryption_key: "CHANGEME_BACKUP_ENCRYPTION_KEY"
|
||||
vault_s3_backup_access_key: "CHANGEME_S3_BACKUP_ACCESS"
|
||||
vault_s3_backup_secret_key: "CHANGEME_S3_BACKUP_SECRET"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# External Services
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_slack_webhook_url: "https://hooks.slack.com/services/CHANGEME"
|
||||
vault_pagerduty_api_key: "CHANGEME_PAGERDUTY_KEY"
|
||||
vault_datadog_api_key: "CHANGEME_DATADOG_KEY"
|
||||
vault_datadog_app_key: "CHANGEME_DATADOG_APP_KEY"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Encryption Keys
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_luks_passphrase: "CHANGEME_LUKS_PASSPHRASE"
|
||||
vault_gpg_passphrase: "CHANGEME_GPG_PASSPHRASE"
|
||||
|
||||
# =============================================================================
|
||||
# Usage in Playbooks
|
||||
# =============================================================================
|
||||
#
|
||||
# Reference vault variables in your playbooks and roles:
|
||||
#
|
||||
# - name: Create user with vault password
|
||||
# user:
|
||||
# name: ansible
|
||||
# password: "{{ vault_ansible_user_password | password_hash('sha512') }}"
|
||||
#
|
||||
# - name: Configure database
|
||||
# mysql_db:
|
||||
# login_password: "{{ vault_mysql_root_password }}"
|
||||
#
|
||||
# =============================================================================
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Production Environment - Libvirt/KVM Dynamic Inventory
|
||||
# =============================================================================
|
||||
#
|
||||
# This inventory uses the custom libvirt_kvm.py plugin to dynamically discover
|
||||
# running VMs on production KVM hypervisors.
|
||||
#
|
||||
# Usage:
|
||||
# ansible-inventory -i inventories/production/libvirt_kvm.yml --list
|
||||
# ansible all -i inventories/production/libvirt_kvm.yml -m ping
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
plugin: libvirt_kvm
|
||||
uri: qemu+ssh://ansible@hypervisor-prod.example.com/system
|
||||
|
||||
# Connection settings
|
||||
connection_timeout: 30
|
||||
ssh_proxy_jump: null # Set to bastion host if needed
|
||||
|
||||
# Filtering
|
||||
states:
|
||||
- running
|
||||
|
||||
# Grouping
|
||||
keyed_groups:
|
||||
- key: tags.environment
|
||||
prefix: env
|
||||
- key: tags.role
|
||||
prefix: role
|
||||
- key: tags.service
|
||||
prefix: service
|
||||
|
||||
# Compose variables
|
||||
compose:
|
||||
ansible_host: "{{ ansible_host | default(ip_address) }}"
|
||||
environment: production
|
||||
|
||||
# Host filters (only include VMs with production tag)
|
||||
# filters:
|
||||
# - tags.environment == 'production'
|
||||
@@ -1,64 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Production Environment - NetBox CMDB Dynamic Inventory (EXAMPLE)
|
||||
# =============================================================================
|
||||
#
|
||||
# This is an example configuration for NetBox dynamic inventory.
|
||||
# Rename to netbox.yml and configure with your NetBox instance details.
|
||||
#
|
||||
# Requirements:
|
||||
# ansible-galaxy collection install netbox.netbox
|
||||
#
|
||||
# Usage:
|
||||
# ansible-inventory -i inventories/production/netbox.yml --list
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
plugin: netbox.netbox.nb_inventory
|
||||
|
||||
# NetBox API Configuration
|
||||
api_endpoint: https://netbox.example.com
|
||||
token: "{{ lookup('env', 'NETBOX_TOKEN') }}" # Use environment variable
|
||||
# OR use vault:
|
||||
# token: "{{ vault_netbox_api_token }}"
|
||||
|
||||
# Validate SSL certificate
|
||||
validate_certs: true
|
||||
|
||||
# Device filters
|
||||
config_context: false
|
||||
group_by:
|
||||
- device_roles
|
||||
- sites
|
||||
- platforms
|
||||
- tags
|
||||
|
||||
# Query filters
|
||||
query_filters:
|
||||
- site: production
|
||||
- status: active
|
||||
|
||||
# Group prefix
|
||||
group_names_raw: false
|
||||
|
||||
# Compose host variables
|
||||
compose:
|
||||
ansible_host: primary_ip4
|
||||
environment: production
|
||||
netbox_site: site.name
|
||||
netbox_role: device_role.name
|
||||
|
||||
# Keyed groups
|
||||
keyed_groups:
|
||||
- key: device_role.name
|
||||
prefix: role
|
||||
- key: site.name
|
||||
prefix: site
|
||||
- key: platform.name
|
||||
prefix: platform
|
||||
|
||||
# Virtual machines
|
||||
virtual_machines: true
|
||||
|
||||
# Interfaces
|
||||
interfaces: true
|
||||
@@ -1,58 +0,0 @@
|
||||
# Staging Inventory
|
||||
|
||||
This directory contains dynamic inventory configurations for the staging environment.
|
||||
|
||||
## Available Inventory Sources
|
||||
|
||||
### 1. Libvirt/KVM Dynamic Inventory (Active)
|
||||
|
||||
**File**: `libvirt_kvm.yml`
|
||||
|
||||
Uses custom libvirt plugin to discover VMs on staging hypervisors.
|
||||
|
||||
```bash
|
||||
# List all staging hosts
|
||||
ansible-inventory -i inventories/staging/libvirt_kvm.yml --list
|
||||
|
||||
# Test connectivity
|
||||
ansible all -i inventories/staging/libvirt_kvm.yml -m ping
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Group Variables
|
||||
|
||||
Add staging-specific variables in:
|
||||
- `group_vars/all.yml` - Global staging settings
|
||||
- `group_vars/all/vault.yml` - Encrypted secrets
|
||||
|
||||
### Host Variables
|
||||
|
||||
Add host-specific variables in:
|
||||
- `host_vars/<hostname>.yml`
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Run against all staging hosts
|
||||
ansible-playbook -i inventories/staging site.yml
|
||||
|
||||
# Run against specific group
|
||||
ansible-playbook -i inventories/staging site.yml --limit webservers
|
||||
|
||||
# Test changes before production
|
||||
ansible-playbook -i inventories/staging site.yml --tags security
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
# Validate inventory syntax
|
||||
ansible-inventory -i inventories/staging --list
|
||||
|
||||
# Check specific host
|
||||
ansible-inventory -i inventories/staging --host hostname
|
||||
|
||||
# Graph inventory structure
|
||||
ansible-inventory -i inventories/staging --graph
|
||||
```
|
||||
@@ -1,164 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Staging Environment - Global Variables
|
||||
# =============================================================================
|
||||
|
||||
# Environment designation
|
||||
environment: staging
|
||||
|
||||
# Ansible connection settings
|
||||
ansible_user: ansible
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
|
||||
# SSH connection settings
|
||||
ansible_ssh_pipelining: true
|
||||
ansible_ssh_extra_args: '-o StrictHostKeyChecking=accept-new'
|
||||
|
||||
# =============================================================================
|
||||
# Network Configuration
|
||||
# =============================================================================
|
||||
|
||||
# NTP servers for time synchronization
|
||||
ntp_servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
|
||||
# DNS servers
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
|
||||
# DNS search domains
|
||||
dns_search_domains:
|
||||
- staging.local
|
||||
|
||||
# =============================================================================
|
||||
# Security Configuration
|
||||
# =============================================================================
|
||||
|
||||
# Automatic security updates
|
||||
security_auto_updates: true
|
||||
security_auto_reboot: false # Can be true for staging
|
||||
security_update_schedule: "daily"
|
||||
|
||||
# Firewall settings
|
||||
firewall_enabled: true
|
||||
firewall_default_policy: deny
|
||||
|
||||
# SELinux/AppArmor enforcement
|
||||
selinux_state: enforcing
|
||||
apparmor_enabled: true
|
||||
|
||||
# SSH hardening
|
||||
ssh_permit_root_login: no
|
||||
ssh_password_authentication: no
|
||||
ssh_gssapi_authentication: no
|
||||
ssh_max_auth_tries: 5
|
||||
ssh_client_alive_interval: 300
|
||||
|
||||
# Audit logging
|
||||
auditd_enabled: true
|
||||
auditd_log_retention_days: 90
|
||||
|
||||
# =============================================================================
|
||||
# Logging and Monitoring
|
||||
# =============================================================================
|
||||
|
||||
# Log retention (shorter for staging)
|
||||
log_retention_days: 90
|
||||
log_compression_enabled: true
|
||||
|
||||
# Syslog configuration
|
||||
syslog_remote_server: null
|
||||
syslog_remote_port: 514
|
||||
|
||||
# Monitoring
|
||||
monitoring_enabled: true
|
||||
monitoring_agent: null
|
||||
|
||||
# =============================================================================
|
||||
# Backup Configuration
|
||||
# =============================================================================
|
||||
|
||||
backup_enabled: true
|
||||
backup_schedule: "0 3 * * *" # Daily at 3 AM
|
||||
backup_retention_days: 14
|
||||
backup_destination: /var/backups
|
||||
|
||||
# =============================================================================
|
||||
# Package Management
|
||||
# =============================================================================
|
||||
|
||||
# Essential packages (CLAUDE.md compliance)
|
||||
essential_packages:
|
||||
- vim
|
||||
- htop
|
||||
- tmux
|
||||
- jq
|
||||
- bc
|
||||
- curl
|
||||
- wget
|
||||
- rsync
|
||||
- git
|
||||
- python3
|
||||
- python3-pip
|
||||
|
||||
# Security packages
|
||||
security_packages:
|
||||
- aide
|
||||
- auditd
|
||||
- chrony
|
||||
|
||||
# Additional tools
|
||||
additional_packages:
|
||||
- net-tools
|
||||
- traceroute
|
||||
- tcpdump
|
||||
- strace
|
||||
- lsof
|
||||
|
||||
# =============================================================================
|
||||
# Performance Tuning
|
||||
# =============================================================================
|
||||
|
||||
# System limits
|
||||
system_max_open_files: 32768
|
||||
system_max_processes: 2048
|
||||
|
||||
# Kernel parameters (sysctl)
|
||||
kernel_parameters:
|
||||
net.ipv4.tcp_syncookies: 1
|
||||
net.ipv4.conf.all.rp_filter: 1
|
||||
net.ipv4.icmp_echo_ignore_broadcasts: 1
|
||||
|
||||
# =============================================================================
|
||||
# Application Configuration
|
||||
# =============================================================================
|
||||
|
||||
# Default application user
|
||||
app_user: appuser
|
||||
app_group: appgroup
|
||||
|
||||
# Application directories
|
||||
app_base_dir: /opt/apps
|
||||
app_data_dir: /var/lib/apps
|
||||
app_log_dir: /var/log/apps
|
||||
|
||||
# =============================================================================
|
||||
# Compliance and Standards
|
||||
# =============================================================================
|
||||
|
||||
# Compliance frameworks
|
||||
compliance_frameworks:
|
||||
- CIS
|
||||
|
||||
# Configuration management
|
||||
config_management_tool: ansible
|
||||
config_management_version: "{{ ansible_version.full }}"
|
||||
|
||||
# =============================================================================
|
||||
# Custom Variables
|
||||
# =============================================================================
|
||||
|
||||
# Add staging-specific custom variables here
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Staging Environment - Encrypted Secrets (EXAMPLE)
|
||||
# =============================================================================
|
||||
#
|
||||
# This is an EXAMPLE vault file. To use:
|
||||
#
|
||||
# 1. Copy this file to vault.yml:
|
||||
# cp vault.yml.example vault.yml
|
||||
#
|
||||
# 2. Fill in actual values (replace CHANGEME placeholders)
|
||||
#
|
||||
# 3. Encrypt with ansible-vault:
|
||||
# ansible-vault encrypt inventories/staging/group_vars/all/vault.yml
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# User Credentials
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_ansible_user_ssh_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ... ansible@example.com"
|
||||
vault_root_password: "CHANGEME_STAGING_ROOT_PASSWORD"
|
||||
vault_ansible_become_password: "CHANGEME_STAGING_SUDO_PASSWORD"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# API Tokens and Keys
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_aws_access_key_id: "CHANGEME_AWS_STAGING_ACCESS_KEY"
|
||||
vault_aws_secret_access_key: "CHANGEME_AWS_STAGING_SECRET_KEY"
|
||||
|
||||
vault_netbox_api_token: "CHANGEME_NETBOX_STAGING_TOKEN"
|
||||
|
||||
vault_gitea_username: "ansible@mymx.me"
|
||||
vault_gitea_password: "79,;,metOND"
|
||||
|
||||
vault_mailcow_username: "ansible@mymx.me"
|
||||
vault_mailcow_password: "79,;,metOND"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Database Credentials (Staging - weaker passwords OK)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_mysql_root_password: "CHANGEME_STAGING_MYSQL"
|
||||
vault_postgresql_postgres_password: "CHANGEME_STAGING_PG"
|
||||
vault_mongodb_admin_password: "CHANGEME_STAGING_MONGO"
|
||||
vault_redis_password: "CHANGEME_STAGING_REDIS"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Application Secrets (Staging)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_app_secret_key: "CHANGEME_STAGING_APP_SECRET"
|
||||
vault_app_api_key: "CHANGEME_STAGING_API_KEY"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Monitoring and Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
vault_grafana_admin_password: "CHANGEME_STAGING_GRAFANA"
|
||||
vault_elasticsearch_password: "CHANGEME_STAGING_ELASTIC"
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Staging Environment - Libvirt/KVM Dynamic Inventory
|
||||
# =============================================================================
|
||||
#
|
||||
# This inventory uses the custom libvirt_kvm.py plugin to dynamically discover
|
||||
# running VMs on staging KVM hypervisors.
|
||||
#
|
||||
# Usage:
|
||||
# ansible-inventory -i inventories/staging/libvirt_kvm.yml --list
|
||||
# ansible all -i inventories/staging/libvirt_kvm.yml -m ping
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
plugin: libvirt_kvm
|
||||
uri: qemu+ssh://ansible@hypervisor-staging.example.com/system
|
||||
|
||||
# Connection settings
|
||||
connection_timeout: 30
|
||||
ssh_proxy_jump: null # Set to bastion host if needed
|
||||
|
||||
# Filtering
|
||||
states:
|
||||
- running
|
||||
|
||||
# Grouping
|
||||
keyed_groups:
|
||||
- key: tags.environment
|
||||
prefix: env
|
||||
- key: tags.role
|
||||
prefix: role
|
||||
- key: tags.service
|
||||
prefix: service
|
||||
|
||||
# Compose variables
|
||||
compose:
|
||||
ansible_host: "{{ ansible_host | default(ip_address) }}"
|
||||
environment: staging
|
||||
|
||||
# Host filters (only include VMs with staging tag)
|
||||
# filters:
|
||||
# - tags.environment == 'staging'
|
||||
2
secrets
2
secrets
Submodule secrets updated: c2241e0e7d...8def011667
Reference in New Issue
Block a user