08_01 Software Packages and Repository Management
Repository Management
# filepath: /playbooks/repo_management.yml
---
- name: Configure Repositories
hosts: all
become: true
tasks:
- name: Add EPEL Repository
dnf:
name: epel-release
state: present
- name: Configure Custom Repository
yum_repository:
name: custom_repo
description: Custom Application Repository
baseurl: http://repo.example.com/custom
gpgcheck: yes
gpgkey: http://repo.example.com/custom/RPM-GPG-KEY
enabled: yes
Package Management
# filepath: /playbooks/package_management.yml
---
- name: Manage Packages
hosts: all
become: true
vars:
packages:
- httpd
- php
- mariadb-server
tasks:
- name: Update all packages
dnf:
name: "*"
state: latest
- name: Install required packages
dnf:
name: "{{ packages }}"
state: present
- name: Remove unused packages
dnf:
autoremove: yes
- name: Clean DNF cache
command: dnf clean all
args:
warn: false
Repository Verification
# filepath: /playbooks/verify_repos.yml
---
- name: Verify Repository Configuration
hosts: all
become: true
tasks:
- name: Get repository list
command: dnf repolist
register: repo_list
changed_when: false
- name: Verify required repositories
assert:
that:
- "'epel' in repo_list.stdout"
- "'custom_repo' in repo_list.stdout"
msg: "Required repositories not found"
Package Updates with Notifications
# filepath: /playbooks/package_updates.yml
---
- name: System Updates
hosts: all
become: true
tasks:
- name: Check for updates
dnf:
list: updates
register: updates
- name: Notify if updates available
debug:
msg: "{{ updates.results | length }} updates available"
when: updates.results | length > 0
- name: Apply security updates
dnf:
name: "*"
security: yes
state: latest
notify: reboot system
handlers:
- name: reboot system
reboot:
msg: "Rebooting due to security updates"
connect_timeout: 5
reboot_timeout: 300
test_command: uptime08_02 Service Management with Ansible
Basic Service Management
# filepath: /examples/service_basics.yml
---
- name: Basic Service Management
hosts: all
become: true
tasks:
- name: Start and enable services
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- httpd
- mariadb
- firewalld
Advanced Service Configuration
# filepath: /examples/service_config.yml
---
- name: Configure Services
hosts: webservers
become: true
vars:
http_port: 80
https_port: 443
tasks:
- name: Deploy Apache configuration
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
validate: '/usr/sbin/httpd -t -f %s'
notify: restart apache
- name: Configure firewall
firewalld:
port: "{{ item }}/tcp"
permanent: yes
state: enabled
loop:
- "{{ http_port }}"
- "{{ https_port }}"
notify: reload firewall
handlers:
- name: restart apache
service:
name: httpd
state: restarted
- name: reload firewall
service:
name: firewalld
state: reloaded
Service Verification
# filepath: /examples/verify_services.yml
---
- name: Verify Service Status
hosts: all
become: true
tasks:
- name: Check service status
service_facts:
- name: Verify critical services
assert:
that:
- ansible_facts.services['httpd.service'].state == 'running'
- ansible_facts.services['httpd.service'].status == 'enabled'
msg: "Service verification failed"
Service Troubleshooting
# filepath: /examples/troubleshoot_services.yml
---
- name: Service Troubleshooting
hosts: all
become: true
tasks:
- name: Get service status
command: systemctl status {{ item }}
register: service_status
ignore_errors: yes
loop:
- httpd
- mariadb
- name: Check service logs
command: journalctl -u {{ item }} --no-pager -n 50
register: service_logs
loop:
- httpd
- mariadb08_03 Firewall Rules Management with Ansible
Basic Firewall Configuration
# filepath: /examples/firewall_basic.yml
---
- name: Basic Firewall Management
hosts: all
become: true
tasks:
- name: Enable firewalld
service:
name: firewalld
state: started
enabled: yes
- name: Allow basic services
firewalld:
service: "{{ item }}"
permanent: yes
state: enabled
loop:
- http
- https
- ssh
Advanced Firewall Rules
# filepath: /examples/firewall_advanced.yml
---
- name: Configure Advanced Firewall Rules
hosts: all
become: true
vars:
custom_ports:
- { port: 8080, proto: tcp }
- { port: 9000, proto: tcp }
tasks:
- name: Configure custom ports
firewalld:
port: "{{ item.port }}/{{ item.proto }}"
permanent: yes
state: enabled
loop: "{{ custom_ports }}"
- name: Add rich rule for IP range
firewalld:
rich_rule: rule family=ipv4 source address=192.168.1.0/24 accept
permanent: yes
state: enabled
Zone Configuration
# filepath: /examples/firewall_zones.yml
---
- name: Configure Firewall Zones
hosts: all
become: true
tasks:
- name: Configure interface zones
firewalld:
zone: internal
interface: eth1
permanent: yes
state: enabled
- name: Set source zones
firewalld:
zone: trusted
source: 192.168.1.0/24
permanent: yes
state: enabled
Port Forwarding
# filepath: /examples/port_forward.yml
---
- name: Configure Port Forwarding
hosts: all
become: true
tasks:
- name: Setup port forwarding
firewalld:
rich_rule: rule family=ipv4 forward-port port=80 protocol=tcp to-port=8080
permanent: yes
state: enabled
notify: reload firewall
handlers:
- name: reload firewall
service:
name: firewalld
state: reloaded08_04 File Systems Management with Ansible
Basic File System Operations
# filepath: /examples/filesystem_basic.yml
---
- name: Basic File System Management
hosts: all
become: true
tasks:
- name: Create partition
parted:
device: /dev/sdb
number: 1
state: present
part_end: 10GiB
- name: Create XFS filesystem
filesystem:
fstype: xfs
dev: /dev/sdb1
- name: Create mount point
file:
path: /data
state: directory
mode: '0755'
- name: Mount filesystem
mount:
path: /data
src: /dev/sdb1
fstype: xfs
state: mounted
LVM Configuration
# filepath: /examples/lvm_config.yml
---
- name: LVM Management
hosts: all
become: true
tasks:
- name: Create Volume Group
lvg:
vg: data_vg
pvs: /dev/sdb1
- name: Create Logical Volume
lvol:
vg: data_vg
lv: data_lv
size: 8g
- name: Create XFS on LV
filesystem:
fstype: xfs
dev: /dev/data_vg/data_lv
Advanced File System Management
# filepath: /examples/filesystem_advanced.yml
---
- name: Advanced File System Tasks
hosts: all
become: true
tasks:
- name: Set XFS Quota
xfs_quota:
mountpoint: /data
name: root
type: user
bhard: 1g
bsoft: 800m
- name: Configure fstab
mount:
path: /data
src: /dev/data_vg/data_lv
fstype: xfs
opts: defaults,noatime
dump: 0
passno: 2
state: present
- name: Set ACLs
acl:
path: /data
entity: apache
etype: user
permissions: rwx
state: present08_05 Storage Device Management with Ansible
Basic Disk Operations
# filepath: /examples/disk_operations.yml
---
- name: Storage Device Management
hosts: all
become: true
tasks:
- name: Get disk information
parted:
device: /dev/sdb
unit: GiB
register: disk_info
- name: Create new partition
parted:
device: /dev/sdb
number: 1
state: present
part_start: 0%
part_end: 100%
LVM Configuration
# filepath: /examples/lvm_setup.yml
---
- name: LVM Management
hosts: all
become: true
tasks:
- name: Create Physical Volume
lvg:
pvs: /dev/sdb1
vg: data_vg
pesize: 32
- name: Create Logical Volumes
lvol:
vg: data_vg
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop:
- { name: 'apps_lv', size: '10g' }
- { name: 'data_lv', size: '20g' }
RAID Configuration
# filepath: /examples/raid_setup.yml
---
- name: RAID Configuration
hosts: all
become: true
tasks:
- name: Create RAID 1
raid:
name: md0
level: 1
devices:
- /dev/sdb1
- /dev/sdc1
state: present
filesystem: xfs
Storage Monitoring
# filepath: /examples/storage_monitor.yml
---
- name: Monitor Storage Devices
hosts: all
become: true
tasks:
- name: Check disk space
command: df -h
register: disk_space
changed_when: false
- name: Check disk health
command: smartctl -H {{ item }}
register: smart_status
loop:
- /dev/sda
- /dev/sdb
ignore_errors: yes
- name: Alert on issues
debug:
msg: "Storage issue detected on {{ inventory_hostname }}"
when: smart_status.rc != 0
Device Encryption
# filepath: /examples/encrypt_storage.yml
---
- name: Configure Encrypted Storage
hosts: all
become: true
tasks:
- name: Setup LUKS encryption
community.crypto.luks_device:
device: /dev/sdb1
state: present
passphrase: "{{ vault_storage_passphrase }}"
- name: Mount encrypted device
mount:
path: /secure
src: /dev/mapper/secure
fstype: xfs
state: mounted08_06 Managing File Content with Ansible
Basic File Operations
# filepath: /examples/file_content.yml
---
- name: File Content Management
hosts: all
become: true
tasks:
- name: Create file with content
copy:
content: |
This is a configuration file
Created by Ansible
dest: /etc/myapp/config.conf
owner: root
group: root
mode: '0644'
backup: yes
Template Management
# filepath: /examples/template_config.yml
---
- name: Template Management
hosts: webservers
vars:
app_port: 8080
app_name: myapp
tasks:
- name: Deploy application config
template:
src: templates/app.conf.j2
dest: /etc/{{ app_name }}/app.conf
validate: '/usr/sbin/nginx -t -c %s'
Line Editing
# filepath: /examples/line_editing.yml
---
- name: Edit File Content
hosts: all
tasks:
- name: Add line to file
lineinfile:
path: /etc/hosts
line: "192.168.1.100 appserver"
- name: Update configuration
replace:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin yes'
replace: 'PermitRootLogin no'
File Permissions
# filepath: /examples/file_permissions.yml
---
- name: Manage File Permissions
hosts: all
become: true
tasks:
- name: Set directory permissions recursively
file:
path: /var/www/html
state: directory
owner: apache
group: apache
mode: '0755'
recurse: yes
Content Verification
# filepath: /examples/verify_content.yml
---
- name: Verify File Content
hosts: all
tasks:
- name: Check file content
command: grep "Required setting" /etc/myapp/config.conf
register: content_check
changed_when: false
failed_when: content_check.rc != 008_07 Ansible Archiving Operations
Basic Archiving
# filepath: /examples/basic_archive.yml
---
- name: Basic Archive Operations
hosts: all
become: true
tasks:
- name: Create tar archive
archive:
path: /var/www/html/
dest: /backup/website.tar.gz
format: gz
Advanced Archiving
# filepath: /examples/advanced_archive.yml
---
- name: Advanced Archive Management
hosts: all
become: true
vars:
backup_dir: /backup
timestamp: "{{ ansible_date_time.date }}"
tasks:
- name: Create backup directory
file:
path: "{{ backup_dir }}"
state: directory
mode: '0750'
- name: Backup configuration files
archive:
path:
- /etc/httpd
- /etc/nginx
- /etc/php
dest: "{{ backup_dir }}/config_{{ timestamp }}.tar.gz"
format: gz
remove: false
- name: Clean old backups
find:
paths: "{{ backup_dir }}"
patterns: "*.tar.gz"
age: 7d
recurse: no
register: old_backups
- name: Remove old backups
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_backups.files }}"
Scheduled Backups
# filepath: /examples/scheduled_backup.yml
---
- name: Configure Scheduled Backups
hosts: all
become: true
tasks:
- name: Create backup script
copy:
dest: /usr/local/bin/backup.sh
mode: '0755'
content: |
#!/bin/bash
tar czf /backup/daily_$(date +%Y%m%d).tar.gz /var/www/html
- name: Add backup cron job
cron:
name: "Daily backup"
hour: "2"
minute: "0"
job: "/usr/local/bin/backup.sh"
Archive Extraction
# filepath: /examples/extract_archive.yml
---
- name: Extract Archives
hosts: all
become: true
tasks:
- name: Extract application archive
unarchive:
src: files/application.tar.gz
dest: /opt/
owner: appuser
group: appgroup
mode: '0755'
remote_src: no08_08 Task Scheduling with Ansible
Cron Job Management
# filepath: /examples/cron_jobs.yml
---
- name: Configure Scheduled Tasks
hosts: all
become: true
tasks:
- name: Setup backup cron
cron:
name: "Daily backup"
hour: "2"
minute: "0"
job: "/usr/local/bin/backup.sh"
- name: Schedule log rotation
cron:
name: "Log rotation"
weekday: "6"
hour: "23"
minute: "30"
job: "/usr/sbin/logrotate /etc/logrotate.conf"
At Jobs
# filepath: /examples/at_jobs.yml
---
- name: Configure At Jobs
hosts: all
become: true
tasks:
- name: Install at package
dnf:
name: at
state: present
- name: Schedule one-time task
at:
command: /usr/local/bin/maintenance.sh
count: 2
units: hours
state: present
Systemd Timers
# filepath: /examples/systemd_timers.yml
---
- name: Configure Systemd Timers
hosts: all
become: true
tasks:
- name: Create timer unit
copy:
dest: /etc/systemd/system/backup.timer
content: |
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
- name: Create service unit
copy:
dest: /etc/systemd/system/backup.service
content: |
[Unit]
Description=Daily Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
- name: Enable and start timer
systemd:
name: backup.timer
enabled: yes
state: started
daemon_reload: yes
Job Monitoring
# filepath: /examples/job_monitoring.yml
---
- name: Monitor Scheduled Tasks
hosts: all
become: true
tasks:
- name: Check cron logs
command: grep CRON /var/log/syslog
register: cron_logs
changed_when: false
- name: Check active timers
command: systemctl list-timers
register: timer_status
changed_when: false08_09 Security Configuration with Ansible
SELinux Management
# filepath: /examples/selinux_config.yml
---
- name: Configure SELinux
hosts: all
become: true
tasks:
- name: Set SELinux mode
selinux:
policy: targeted
state: enforcing
- name: Set SELinux booleans
seboolean:
name: "{{ item }}"
state: yes
persistent: yes
loop:
- httpd_can_network_connect
- httpd_can_network_connect_db
SSH Hardening
# filepath: /examples/ssh_security.yml
---
- name: Secure SSH Configuration
hosts: all
become: true
tasks:
- name: Configure SSH
template:
src: templates/sshd_config.j2
dest: /etc/ssh/sshd_config
validate: '/usr/sbin/sshd -t -f %s'
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
Security Auditing
# filepath: /examples/security_audit.yml
---
- name: Security Audit
hosts: all
become: true
tasks:
- name: Check failed logins
command: grep "Failed password" /var/log/secure
register: failed_logins
changed_when: false
ignore_errors: yes
- name: Check open ports
command: ss -tuln
register: open_ports
changed_when: false
- name: Verify permissions
stat:
path: "{{ item }}"
loop:
- /etc/shadow
- /etc/passwd
- /etc/group
register: file_perms
User Security
# filepath: /examples/user_security.yml
---
- name: Configure User Security
hosts: all
become: true
tasks:
- name: Set password policy
lineinfile:
path: /etc/security/pwquality.conf
regexp: "^{{ item.param }}="
line: "{{ item.param }}={{ item.value }}"
loop:
- { param: 'minlen', value: '12' }
- { param: 'minclass', value: '4' }
- { param: 'maxrepeat', value: '3' }08_10 User and Group Management with Ansible
Basic User Management
# filepath: /examples/user_management.yml
---
- name: Manage Users
hosts: all
become: true
vars:
users:
- name: john
groups: ['developers', 'docker']
shell: /bin/bash
- name: mary
groups: ['admins']
shell: /bin/zsh
tasks:
- name: Create user groups
group:
name: "{{ item }}"
state: present
loop:
- developers
- admins
- docker
- name: Create users
user:
name: "{{ item.name }}"
groups: "{{ item.groups | join(',') }}"
shell: "{{ item.shell }}"
password: "{{ 'changeme' | password_hash('sha512') }}"
update_password: on_create
loop: "{{ users }}"
Sudo Configuration
# filepath: /examples/sudo_config.yml
---
- name: Configure Sudo Access
hosts: all
become: true
tasks:
- name: Setup sudo rules
copy:
dest: /etc/sudoers.d/custom
content: |
%admins ALL=(ALL) NOPASSWD: ALL
%developers ALL=(ALL) /usr/bin/docker
validate: /usr/sbin/visudo -cf %s
mode: '0440'
Password Policies
# filepath: /examples/password_policy.yml
---
- name: Configure Password Policies
hosts: all
become: true
tasks:
- name: Set password aging
lineinfile:
path: /etc/login.defs
regexp: "^{{ item.param }}"
line: "{{ item.param }} {{ item.value }}"
loop:
- { param: "PASS_MAX_DAYS", value: "90" }
- { param: "PASS_MIN_DAYS", value: "7" }
- { param: "PASS_WARN_AGE", value: "14" }
Group Membership Management
# filepath: /examples/group_management.yml
---
- name: Manage Group Memberships
hosts: all
become: true
tasks:
- name: Add users to groups
user:
name: "{{ item.user }}"
groups: "{{ item.groups }}"
append: yes
loop:
- { user: 'john', groups: 'wheel' }
- { user: 'mary', groups: 'sudo' }Discover more from Altgr Blog
Subscribe to get the latest posts sent to your email.
