[RHCE] 05 – Configure Ansible managed nodes

    05_01 SSH Key Distribution for Ansible

    Key Generation Script

    # filepath: /scripts/generate_keys.ps1
    # Generate SSH key pair
    ssh-keygen -t rsa -b 4096 -f C:\Users\ansible\.ssh\ansible -N '""'
    

    Linux Distribution Script

    # filepath: /scripts/distribute_keys.sh
    #!/bin/bash
    # Distribute SSH keys to managed nodes
    
    # List of managed nodes
    NODES="node1.example.com node2.example.com"
    KEY_FILE="~/.ssh/ansible.pub"
    
    for node in $NODES; do
        ssh-copy-id -i $KEY_FILE ansible@$node
    done
    

    Windows Distribution Script

    # filepath: /scripts/distribute_keys.ps1
    # Server list
    $servers = @(
        "node1.example.com",
        "node2.example.com"
    )
    
    # Copy SSH key
    foreach ($server in $servers) {
        type $env:USERPROFILE\.ssh\ansible.pub | ssh ansible@$server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
    }
    

    SSH Config File

    # filepath: ~/.ssh/config
    Host *.example.com
        User ansible
        IdentityFile ~/.ssh/ansible
        StrictHostKeyChecking no
    

    Verification Script

    # filepath: /scripts/verify_ssh.ps1
    # Test SSH connectivity
    $servers = Get-Content servers.txt
    
    foreach ($server in $servers) {
        Write-Host "Testing connection to $server..."
        ssh -i ~/.ssh/ansible -o BatchMode=yes ansible@$server "hostname"
    }
    

    Recovery Script

    # filepath: /scripts/backup_keys.sh
    #!/bin/bash
    # Backup SSH keys
    tar czf ssh_backup_$(date +%F).tar.gz ~/.ssh/

    05_02 Privilege Escalation Configuration

    Sudoers Configuration

    # filepath: /etc/sudoers.d/ansible
    ansible ALL=(ALL) NOPASSWD: ALL
    

    Configure Ansible User

    # filepath: /scripts/configure_sudo.sh
    #!/bin/bash
    # Add ansible user to wheel group
    usermod -aG wheel ansible
    
    # Set secure permissions
    chmod 440 /etc/sudoers.d/ansible
    chown root:root /etc/sudoers.d/ansible
    

    Ansible Configuration

    # filepath: /etc/ansible/ansible.cfg
    [privilege_escalation]
    become = True
    become_method = sudo
    become_user = root
    become_ask_pass = False
    

    Verification Script

    # filepath: /scripts/verify_sudo.sh
    #!/bin/bash
    # Test sudo access
    sudo -l -U ansible
    
    # Test with Ansible
    ansible all -m command -a "whoami" -b
    

    Windows Node Configuration

    # filepath: /scripts/configure_win_admin.ps1
    # Add ansible user to administrators group
    Add-LocalGroupMember -Group "Administrators" -Member "ansible"
    
    # Configure WinRM
    winrm quickconfig
    Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true
    

    Troubleshooting Script

    # filepath: /scripts/troubleshoot_sudo.sh
    #!/bin/bash
    # Check sudo configuration
    visudo -c
    
    # Check ansible user groups
    groups ansible
    
    # Check sudoers.d permissions
    ls -l /etc/sudoers.d/ansible

    05_03 File Deployment to Managed Nodes

    Basic File Copy

    # filepath: /playbooks/file_deploy.yml
    ---
    - name: Deploy Files
      hosts: all
      tasks:
        - name: Copy configuration file
          copy:
            src: files/app.conf
            dest: /etc/app/app.conf
            owner: root
            group: root
            mode: '0644'
    

    Template Deployment

    # filepath: /playbooks/template_deploy.yml
    ---
    - name: Deploy Templates
      hosts: webservers
      vars:
        http_port: 80
        server_name: example.com
      tasks:
        - name: Deploy web configuration
          template:
            src: templates/vhost.conf.j2
            dest: /etc/httpd/conf.d/vhost.conf
            validate: '/usr/sbin/httpd -t -f %s'
    

    Complete Deployment Example

    # filepath: /playbooks/full_deploy.yml
    ---
    - name: Full Application Deployment
      hosts: production
      vars_files:
        - vars/app_vars.yml
        
      tasks:
        - name: Create directory structure
          file:
            path: "{{ item }}"
            state: directory
            mode: '0755'
          loop:
            - /opt/app/config
            - /opt/app/data
            - /opt/app/logs
    
        - name: Deploy application files
          copy:
            src: "files/{{ item }}"
            dest: "/opt/app/{{ item }}"
            owner: appuser
            group: appgroup
            mode: '0644'
          loop:
            - app.properties
            - config.xml
            - data.json
    
        - name: Deploy templates
          template:
            src: "templates/{{ item.src }}"
            dest: "/opt/app/config/{{ item.dest }}"
            owner: appuser
            group: appgroup
            mode: '0640'
          loop:
            - { src: 'app.conf.j2', dest: 'app.conf' }
            - { src: 'logging.conf.j2', dest: 'logging.conf' }
    

    Verification Tasks

    # filepath: /playbooks/verify_deploy.yml
    ---
    - name: Verify Deployment
      hosts: all
      tasks:
        - name: Check file existence
          stat:
            path: "/opt/app/config/app.conf"
          register: config_file
    
        - name: Verify permissions
          fail:
            msg: "Incorrect permissions on config file"
          when: config_file.stat.mode != "0640"

    05_04 Converting Shell Scripts to Ansible Playbooks

    Example 1: Basic System Setup Script

    Original Shell Script

    # filepath: /scripts/setup_system.sh
    #!/bin/bash
    yum update -y
    yum install -y httpd php mysql
    systemctl start httpd
    systemctl enable httpd
    firewall-cmd --permanent --add-service=http
    firewall-cmd --reload
    

    Converted Ansible Playbook

    # filepath: /playbooks/setup_system.yml
    ---
    - name: System Setup
      hosts: webservers
      become: true
      tasks:
        - name: Update system packages
          dnf:
            name: "*"
            state: latest
        
        - name: Install required packages
          dnf:
            name:
              - httpd
              - php
              - mysql
            state: present
        
        - name: Start and enable Apache
          service:
            name: httpd
            state: started
            enabled: yes
        
        - name: Configure firewall
          firewalld:
            service: http
            permanent: yes
            state: enabled
          notify: reload firewall
    
      handlers:
        - name: reload firewall
          command: firewall-cmd --reload
    

    Example 2: User Management Script

    Original Shell Script

    # filepath: /scripts/manage_users.sh
    #!/bin/bash
    for user in john mary steve; do
        useradd $user
        echo "password123" | passwd --stdin $user
        mkdir -p /home/$user/.ssh
        chmod 700 /home/$user/.ssh
        chown $user:$user /home/$user/.ssh
    done
    

    Converted Ansible Playbook

    # filepath: /playbooks/manage_users.yml
    ---
    - name: User Management
      hosts: all
      become: true
      vars:
        users:
          - john
          - mary
          - steve
        
      tasks:
        - name: Create users
          user:
            name: "{{ item }}"
            state: present
            password: "{{ 'password123' | password_hash('sha512') }}"
          loop: "{{ users }}"
        
        - name: Create SSH directories
          file:
            path: "/home/{{ item }}/.ssh"
            state: directory
            mode: '0700'
            owner: "{{ item }}"
            group: "{{ item }}"
          loop: "{{ users }}"
    

    Example 3: Backup Script

    Original Shell Script

    # filepath: /scripts/backup.sh
    #!/bin/bash
    BACKUP_DIR="/backup"
    DATE=$(date +%Y%m%d)
    tar -czf $BACKUP_DIR/etc_$DATE.tar.gz /etc
    find $BACKUP_DIR -type f -mtime +7 -delete
    

    Converted Ansible Playbook

    # filepath: /playbooks/backup.yml
    ---
    - name: System Backup
      hosts: all
      become: true
      vars:
        backup_dir: /backup
        
      tasks:
        - name: Ensure backup directory exists
          file:
            path: "{{ backup_dir }}"
            state: directory
            mode: '0750'
        
        - name: Create backup
          archive:
            path: /etc
            dest: "{{ backup_dir }}/etc_{{ ansible_date_time.date }}.tar.gz"
            format: gz
        
        - name: Remove old backups
          find:
            paths: "{{ backup_dir }}"
            age: 7d
            patterns: "*.tar.gz"
            recurse: no
          register: old_backups
        
        - name: Delete old backups
          file:
            path: "{{ item.path }}"
            state: absent
          loop: "{{ old_backups.files }}"


    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *