Add Ansible configuration and roles for development environment setup. Introduced ansible.cfg for default settings, created README.md for documentation, and established roles for applications, base, and development tasks. Enhanced dev-playbook.yml with pre-tasks and streamlined application installations.
This commit is contained in:
parent
fe5c39f487
commit
8b403e3aa5
181
README.md
Normal file
181
README.md
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
# Ansible Development Environment Setup
|
||||||
|
|
||||||
|
This Ansible playbook automates the setup of development environments across multiple machines.
|
||||||
|
|
||||||
|
## 🏗️ Architecture
|
||||||
|
|
||||||
|
### Host Groups
|
||||||
|
- `dev`: Development machines (devVM, bottom, debianDesktopVM)
|
||||||
|
- `gitea`: Gitea server
|
||||||
|
- `portainer`: Portainer container management
|
||||||
|
- `homepage`: Homepage dashboard
|
||||||
|
- `ansible`: Ansible control node
|
||||||
|
|
||||||
|
### Roles
|
||||||
|
|
||||||
|
#### Core Roles
|
||||||
|
- **`maintenance`**: System updates, package cleanup, and reboots
|
||||||
|
- **`base`**: Core system packages, security tools, and system hardening
|
||||||
|
- **`development`**: Development tools (git, nodejs, build-essential, python3)
|
||||||
|
- **`shell`**: Shell configuration (zsh + oh-my-zsh + powerlevel10k)
|
||||||
|
- **`docker`**: Docker CE installation and user configuration
|
||||||
|
- **`ssh`**: SSH server and firewall configuration
|
||||||
|
- **`user`**: User management
|
||||||
|
|
||||||
|
#### Application Roles
|
||||||
|
- **`applications`**: Desktop applications (Brave, LibreOffice, Redshift, Evince)
|
||||||
|
- **`snap`**: Snap daemon and snap applications (VSCode, Cursor)
|
||||||
|
|
||||||
|
## 🚀 Usage
|
||||||
|
|
||||||
|
### Basic Setup
|
||||||
|
```bash
|
||||||
|
# Run on all development machines
|
||||||
|
ansible-playbook dev-playbook.yml
|
||||||
|
|
||||||
|
# Run on specific host
|
||||||
|
ansible-playbook dev-playbook.yml --limit devVM
|
||||||
|
|
||||||
|
# Skip reboots for specific host
|
||||||
|
ansible-playbook dev-playbook.yml --limit bottom
|
||||||
|
```
|
||||||
|
|
||||||
|
### Skip Reboots
|
||||||
|
Add `skip_reboot=true` to host variables:
|
||||||
|
```ini
|
||||||
|
[dev]
|
||||||
|
bottom ansible_host=10.0.10.156 ansible_user=beast skip_reboot=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dry Run
|
||||||
|
```bash
|
||||||
|
# Check what would be changed
|
||||||
|
ansible-playbook dev-playbook.yml --check
|
||||||
|
|
||||||
|
# Verbose output
|
||||||
|
ansible-playbook dev-playbook.yml -v
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Global Variables (`group_vars/all.yml`)
|
||||||
|
- `timezone`: System timezone (default: UTC)
|
||||||
|
- `locale`: System locale (default: en_US.UTF-8)
|
||||||
|
- `fail2ban_bantime`: Ban duration in seconds
|
||||||
|
- `fail2ban_findtime`: Time window for failures
|
||||||
|
- `fail2ban_maxretry`: Max failures before ban
|
||||||
|
|
||||||
|
### Host Variables (`host_vars/`)
|
||||||
|
- `skip_reboot`: Skip automatic reboots
|
||||||
|
- Encrypted variables for sensitive data
|
||||||
|
|
||||||
|
## 🛡️ Security Features
|
||||||
|
|
||||||
|
### Fail2ban Configuration
|
||||||
|
- SSH brute force protection
|
||||||
|
- Configurable ban times and retry limits
|
||||||
|
- Email notifications (configured in template)
|
||||||
|
|
||||||
|
### UFW Firewall
|
||||||
|
- Deny-by-default policy
|
||||||
|
- SSH access allowed
|
||||||
|
- Automatic enablement
|
||||||
|
|
||||||
|
### System Hardening
|
||||||
|
- Timezone and locale configuration
|
||||||
|
- Security package installation
|
||||||
|
- Monitoring tools (htop, iotop, nethogs, logwatch)
|
||||||
|
|
||||||
|
## 📦 Installed Packages
|
||||||
|
|
||||||
|
### Base System
|
||||||
|
- `htop`, `curl`, `wget`, `unzip`, `xclip`
|
||||||
|
- `net-tools`, `ufw`, `fail2ban`
|
||||||
|
- `iotop`, `nethogs`, `logwatch`
|
||||||
|
|
||||||
|
### Development Tools
|
||||||
|
- `git`, `nodejs`, `npm`
|
||||||
|
- `build-essential`, `python3`, `python3-pip`
|
||||||
|
|
||||||
|
### Applications
|
||||||
|
- `brave-browser`, `libreoffice`, `evince`, `redshift`
|
||||||
|
- `code` (VSCode), `cursor` (via snap)
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
- Docker CE with all components
|
||||||
|
- Docker Compose
|
||||||
|
- User added to docker group
|
||||||
|
|
||||||
|
## 🔄 Maintenance
|
||||||
|
|
||||||
|
### Automatic Updates
|
||||||
|
The maintenance role handles:
|
||||||
|
- Package updates (`apt upgrade`)
|
||||||
|
- Unused package removal (`apt autoremove`)
|
||||||
|
- Cache cleanup (`apt autoclean`)
|
||||||
|
- Conditional reboots
|
||||||
|
|
||||||
|
### Manual Maintenance
|
||||||
|
```bash
|
||||||
|
# Update only maintenance role
|
||||||
|
ansible-playbook dev-playbook.yml --tags maintenance
|
||||||
|
|
||||||
|
# Skip maintenance
|
||||||
|
ansible-playbook dev-playbook.yml --skip-tags maintenance
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **SSH Connection Issues**
|
||||||
|
- Check `ansible.cfg` SSH settings
|
||||||
|
- Verify host keys and user permissions
|
||||||
|
|
||||||
|
2. **Package Installation Failures**
|
||||||
|
- Run with `-v` for verbose output
|
||||||
|
- Check internet connectivity on target hosts
|
||||||
|
|
||||||
|
3. **Reboot Issues**
|
||||||
|
- Use `skip_reboot=true` for problematic hosts
|
||||||
|
- Check maintenance role handlers
|
||||||
|
|
||||||
|
### Debug Commands
|
||||||
|
```bash
|
||||||
|
# Test connectivity
|
||||||
|
ansible dev -m ping
|
||||||
|
|
||||||
|
# Check facts
|
||||||
|
ansible dev -m setup
|
||||||
|
|
||||||
|
# Run specific role
|
||||||
|
ansible-playbook dev-playbook.yml --tags base
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 File Structure
|
||||||
|
```
|
||||||
|
ansible/
|
||||||
|
├── ansible.cfg # Ansible configuration
|
||||||
|
├── hosts # Inventory file
|
||||||
|
├── dev-playbook.yml # Main development playbook
|
||||||
|
├── group_vars/
|
||||||
|
│ └── all.yml # Global variables
|
||||||
|
├── host_vars/ # Host-specific variables
|
||||||
|
└── roles/
|
||||||
|
├── maintenance/ # System maintenance
|
||||||
|
├── base/ # Core system setup
|
||||||
|
├── development/ # Development tools
|
||||||
|
├── shell/ # Shell configuration
|
||||||
|
├── docker/ # Docker installation
|
||||||
|
├── ssh/ # SSH configuration
|
||||||
|
├── user/ # User management
|
||||||
|
├── applications/ # Desktop applications
|
||||||
|
└── snap/ # Snap applications
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
1. Test changes with `--check` first
|
||||||
|
2. Update documentation for new roles/tasks
|
||||||
|
3. Use proper handlers for service restarts
|
||||||
|
4. Follow existing naming conventions
|
||||||
11
ansible.cfg
11
ansible.cfg
@ -0,0 +1,11 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = hosts
|
||||||
|
host_key_checking = True
|
||||||
|
timeout = 30
|
||||||
|
gathering = smart
|
||||||
|
fact_caching = memory
|
||||||
|
stdout_callback = yaml
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o IdentitiesOnly=yes
|
||||||
|
pipelining = True
|
||||||
@ -9,89 +9,17 @@
|
|||||||
- docker
|
- docker
|
||||||
- ssh
|
- ssh
|
||||||
- user
|
- user
|
||||||
|
- applications
|
||||||
|
- snap
|
||||||
|
|
||||||
tasks:
|
pre_tasks:
|
||||||
- name: Update apt cache
|
- name: Update apt cache
|
||||||
apt:
|
apt:
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
|
run_once: true
|
||||||
|
|
||||||
- name: Enable 'universe' repo (Ubuntu and Mint only)
|
tasks:
|
||||||
command: add-apt-repository universe
|
# Additional tasks can be added here if needed
|
||||||
when: ansible_facts['distribution'] in ["Ubuntu", "Linux Mint"]
|
- name: Display completion message
|
||||||
changed_when: false
|
debug:
|
||||||
ignore_errors: true
|
msg: "Development environment setup completed successfully!"
|
||||||
|
|
||||||
- name: Remove Mint’s nosnap.pref block (Mint only)
|
|
||||||
file:
|
|
||||||
path: /etc/apt/preferences.d/nosnap.pref
|
|
||||||
state: absent
|
|
||||||
when: ansible_facts['distribution'] == "Linux Mint"
|
|
||||||
|
|
||||||
- name: Install Redshift
|
|
||||||
apt:
|
|
||||||
name: redshift
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Modern Brave repo/key installation for all
|
|
||||||
- name: Download Brave APT key
|
|
||||||
get_url:
|
|
||||||
url: https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg
|
|
||||||
dest: /usr/share/keyrings/brave-browser-archive-keyring.gpg
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Add Brave repo (all Debian family)
|
|
||||||
apt_repository:
|
|
||||||
repo: "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main"
|
|
||||||
filename: brave-browser
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Update apt cache after repo add
|
|
||||||
apt:
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Install Brave browser
|
|
||||||
apt:
|
|
||||||
name: brave-browser
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Snap daemon install across all Debian family systems
|
|
||||||
- name: Install Snap daemon
|
|
||||||
apt:
|
|
||||||
name: snapd
|
|
||||||
state: present
|
|
||||||
when: ansible_facts['os_family'] == "Debian"
|
|
||||||
|
|
||||||
# Ensure snapd is running on Debian (optional, improves reliability)
|
|
||||||
- name: Enable snapd socket on Debian
|
|
||||||
systemd:
|
|
||||||
name: snapd.socket
|
|
||||||
enabled: true
|
|
||||||
state: started
|
|
||||||
when: ansible_facts['distribution'] == "Debian"
|
|
||||||
|
|
||||||
- name: Force Ansible to reload facts
|
|
||||||
setup:
|
|
||||||
|
|
||||||
# Install IDE and other snaps everywhere Snap is available
|
|
||||||
- name: Install VSCode IDE (Snap, all distros)
|
|
||||||
community.general.snap:
|
|
||||||
name: code
|
|
||||||
classic: true
|
|
||||||
state: present
|
|
||||||
when: ansible_facts['os_family'] == "Debian"
|
|
||||||
|
|
||||||
- name: Install Cursor (Snap, all distros)
|
|
||||||
community.general.snap:
|
|
||||||
name: cursor
|
|
||||||
state: present
|
|
||||||
when: ansible_facts['os_family'] == "Debian"
|
|
||||||
|
|
||||||
- name: Install LibreOffice
|
|
||||||
apt:
|
|
||||||
name: libreoffice
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Install PDF reader (Evince)
|
|
||||||
apt:
|
|
||||||
name: evince
|
|
||||||
state: present
|
|
||||||
|
|||||||
10
group_vars/all.yml
Normal file
10
group_vars/all.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
# Common variables for all hosts
|
||||||
|
timezone: UTC
|
||||||
|
locale: en_US.UTF-8
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
fail2ban_bantime: 3600
|
||||||
|
fail2ban_findtime: 600
|
||||||
|
fail2ban_maxretry: 3
|
||||||
2
roles/applications/meta/main.yml
Normal file
2
roles/applications/meta/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
dependencies: []
|
||||||
25
roles/applications/tasks/main.yml
Normal file
25
roles/applications/tasks/main.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
- name: Install desktop applications
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- redshift
|
||||||
|
- libreoffice
|
||||||
|
- evince
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Download Brave APT key
|
||||||
|
get_url:
|
||||||
|
url: https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg
|
||||||
|
dest: /usr/share/keyrings/brave-browser-archive-keyring.gpg
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Add Brave repo (all Debian family)
|
||||||
|
apt_repository:
|
||||||
|
repo: "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main"
|
||||||
|
filename: brave-browser
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Brave browser
|
||||||
|
apt:
|
||||||
|
name: brave-browser
|
||||||
|
state: present
|
||||||
@ -1,2 +1,11 @@
|
|||||||
---
|
---
|
||||||
# handlers file for base
|
# handlers file for base
|
||||||
|
|
||||||
|
- name: restart fail2ban
|
||||||
|
systemd:
|
||||||
|
name: fail2ban
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: reload ufw
|
||||||
|
ufw:
|
||||||
|
state: reloaded
|
||||||
|
|||||||
@ -10,3 +10,40 @@
|
|||||||
state: present
|
state: present
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Install admin tools
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- net-tools
|
||||||
|
- ufw
|
||||||
|
- fail2ban
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install monitoring tools
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- iotop
|
||||||
|
- nethogs
|
||||||
|
- logwatch
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Configure fail2ban
|
||||||
|
template:
|
||||||
|
src: jail.local.j2
|
||||||
|
dest: /etc/fail2ban/jail.local
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart fail2ban
|
||||||
|
|
||||||
|
- name: Enable UFW
|
||||||
|
ufw:
|
||||||
|
state: enabled
|
||||||
|
policy: deny
|
||||||
|
|
||||||
|
- name: Set timezone
|
||||||
|
timezone:
|
||||||
|
name: "{{ timezone | default('UTC') }}"
|
||||||
|
|
||||||
|
- name: Configure locale
|
||||||
|
locale_gen:
|
||||||
|
name: "{{ locale | default('en_US.UTF-8') }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
|||||||
33
roles/base/templates/jail.local.j2
Normal file
33
roles/base/templates/jail.local.j2
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
# Ban hosts for 1 hour
|
||||||
|
bantime = 3600
|
||||||
|
# Check for repeated failures for 10 minutes
|
||||||
|
findtime = 600
|
||||||
|
# Allow 3 failures before banning
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
# Email notifications (uncomment and configure if needed)
|
||||||
|
destemail = idobkin@gmail.com
|
||||||
|
sender = idobkin@gmail.com
|
||||||
|
action = %(action_mwl)s
|
||||||
|
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = ssh
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
[apache]
|
||||||
|
enabled = false
|
||||||
|
port = http,https
|
||||||
|
filter = apache-auth
|
||||||
|
logpath = /var/log/apache2/error.log
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
[nginx-http-auth]
|
||||||
|
enabled = false
|
||||||
|
port = http,https
|
||||||
|
filter = nginx-http-auth
|
||||||
|
logpath = /var/log/nginx/error.log
|
||||||
|
maxretry = 3
|
||||||
@ -6,3 +6,16 @@
|
|||||||
- nodejs
|
- nodejs
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Install build tools
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- build-essential
|
||||||
|
- python3
|
||||||
|
- python3-pip
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install npm
|
||||||
|
apt:
|
||||||
|
name: npm
|
||||||
|
state: present
|
||||||
|
|
||||||
|
|||||||
@ -10,3 +10,36 @@
|
|||||||
state: present
|
state: present
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Add Docker's official GPG key
|
||||||
|
apt_key:
|
||||||
|
url: https://download.docker.com/linux/ubuntu/gpg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add Docker repository
|
||||||
|
apt_repository:
|
||||||
|
repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Docker CE
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
- docker-buildx-plugin
|
||||||
|
- docker-compose-plugin
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Start and enable Docker service
|
||||||
|
systemd:
|
||||||
|
name: docker
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
- name: Add user to docker group
|
||||||
|
user:
|
||||||
|
name: "{{ ansible_user }}"
|
||||||
|
groups: docker
|
||||||
|
append: yes
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,11 @@
|
|||||||
---
|
---
|
||||||
# handlers file for maintenance
|
# handlers file for maintenance
|
||||||
|
|
||||||
|
- name: restart fail2ban
|
||||||
|
systemd:
|
||||||
|
name: fail2ban
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: reload ufw
|
||||||
|
ufw:
|
||||||
|
state: reloaded
|
||||||
|
|||||||
5
roles/snap/handlers/main.yml
Normal file
5
roles/snap/handlers/main.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: restart snapd
|
||||||
|
systemd:
|
||||||
|
name: snapd
|
||||||
|
state: restarted
|
||||||
2
roles/snap/meta/main.yml
Normal file
2
roles/snap/meta/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
dependencies: []
|
||||||
42
roles/snap/tasks/main.yml
Normal file
42
roles/snap/tasks/main.yml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
- name: Enable 'universe' repo (Ubuntu and Mint only)
|
||||||
|
command: add-apt-repository universe
|
||||||
|
when: ansible_facts['distribution'] in ["Ubuntu", "Linux Mint"]
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove Mint's nosnap.pref block (Mint only)
|
||||||
|
file:
|
||||||
|
path: /etc/apt/preferences.d/nosnap.pref
|
||||||
|
state: absent
|
||||||
|
when: ansible_facts['distribution'] == "Linux Mint"
|
||||||
|
|
||||||
|
- name: Install Snap daemon
|
||||||
|
apt:
|
||||||
|
name: snapd
|
||||||
|
state: present
|
||||||
|
when: ansible_facts['os_family'] == "Debian"
|
||||||
|
notify: restart snapd
|
||||||
|
|
||||||
|
- name: Enable snapd socket on Debian
|
||||||
|
systemd:
|
||||||
|
name: snapd.socket
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
when: ansible_facts['distribution'] == "Debian"
|
||||||
|
|
||||||
|
- name: Force Ansible to reload facts
|
||||||
|
setup:
|
||||||
|
|
||||||
|
- name: Install VSCode IDE (Snap, all distros)
|
||||||
|
community.general.snap:
|
||||||
|
name: code
|
||||||
|
classic: true
|
||||||
|
state: present
|
||||||
|
when: ansible_facts['os_family'] == "Debian"
|
||||||
|
|
||||||
|
- name: Install Cursor (Snap, all distros)
|
||||||
|
community.general.snap:
|
||||||
|
name: cursor
|
||||||
|
state: present
|
||||||
|
when: ansible_facts['os_family'] == "Debian"
|
||||||
@ -4,3 +4,8 @@
|
|||||||
name: openssh-server
|
name: openssh-server
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Configure firewalls
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
name: OpenSSH
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
- name: Ensure ladmin user exists
|
- name: Ensure user exists
|
||||||
user:
|
user:
|
||||||
name: "{{ ansible_user }}"
|
name: "{{ ansible_user }}"
|
||||||
state: present
|
state: present
|
||||||
shell: /bin/bash
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user