<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gbenga Akinbajo Okunniyi</title>
    <description>The latest articles on DEV Community by Gbenga Akinbajo Okunniyi (@gbenga_okunniyi).</description>
    <link>https://dev.to/gbenga_okunniyi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1281857%2F86ca7dcf-0897-4894-8005-29db3fa2c085.png</url>
      <title>DEV Community: Gbenga Akinbajo Okunniyi</title>
      <link>https://dev.to/gbenga_okunniyi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gbenga_okunniyi"/>
    <language>en</language>
    <item>
      <title>User account creation using BASH</title>
      <dc:creator>Gbenga Akinbajo Okunniyi</dc:creator>
      <pubDate>Thu, 04 Jul 2024 15:26:47 +0000</pubDate>
      <link>https://dev.to/gbenga_okunniyi/user-account-creation-using-bash-39p3</link>
      <guid>https://dev.to/gbenga_okunniyi/user-account-creation-using-bash-39p3</guid>
      <description>&lt;p&gt;Introduction&lt;br&gt;
In today's fast-paced development environments, automation is key to managing system operations efficiently. As a SysOps engineer, automating the process of creating user accounts, setting up their groups, and managing passwords can save a significant amount of time and reduce errors. This guide walks you through a Bash script designed to automate these tasks, providing detailed explanations for each step.&lt;/p&gt;

&lt;p&gt;The Script&lt;br&gt;
The script, create_users.sh, performs the following tasks:&lt;/p&gt;

&lt;p&gt;Reads a text file containing usernames and group names.&lt;br&gt;
Creates users and assigns them to specified groups.&lt;br&gt;
Sets up home directories with appropriate permissions.&lt;br&gt;
Generates random passwords for the users.&lt;br&gt;
Logs all actions to /var/log/user_management.log.&lt;br&gt;
Stores generated passwords securely in /var/secure/user_passwords.csv.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Log file
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Check if the text file is provided
if [ -z "$1" ]; then
    echo "Usage: $0 &amp;lt;name-of-text-file&amp;gt;"
    exit 1
fi

# Check if the file exists
if [ ! -f "$1" ]; then
    echo "File $1 does not exist."
    exit 1
fi

# Create necessary directories and files
mkdir -p /var/secure
touch $LOG_FILE
touch $PASSWORD_FILE

# Set permissions for the password file
chmod 600 $PASSWORD_FILE

# Function to generate random passwords
generate_password() {
    tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 12
}

# Read the file line by line
while IFS=';' read -r user groups; do
    # Remove whitespace
    user=$(echo "$user" | xargs)
    groups=$(echo "$groups" | xargs)

    # Check if the user already exists
    if id "$user" &amp;amp;&amp;gt;/dev/null; then
        echo "User $user already exists. Skipping password setting." | tee -a $LOG_FILE
        continue
    fi

    # Create the user's personal group if it doesn't exist
    if ! getent group "$user" &amp;gt;/dev/null; then
        groupadd "$user"
        echo "Group $user created." | tee -a $LOG_FILE
    fi

    # Create the user and assign the personal group as their primary group
    useradd -m -g "$user" "$user"
    if [ $? -eq 0 ]; then
        echo "User $user created successfully." | tee -a $LOG_FILE
    else
        echo "Failed to create user $user." | tee -a $LOG_FILE
        continue
    fi

    # Add the user to additional groups
    if [ -n "$groups" ]; then
        IFS=',' read -ra group_array &amp;lt;&amp;lt;&amp;lt; "$groups"
        for group in "${group_array[@]}"; do
            group=$(echo "$group" | xargs)
            if ! getent group "$group" &amp;gt;/dev/null; then
                groupadd "$group"
                echo "Group $group created." | tee -a $LOG_FILE
            fi
            usermod -aG "$group" "$user"
            echo "User $user added to group $group." | tee -a $LOG_FILE
        done
    fi

    # Generate a random password
    password=$(generate_password)
    echo "$user:$password" | chpasswd

    # Store the password securely
    echo "$user,$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    echo "Password for user $user set and stored securely." | tee -a $LOG_FILE

done &amp;lt; "$1"

echo "User creation process completed. Check $LOG_FILE for details."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation&lt;br&gt;
Log and Password Files&lt;/p&gt;

&lt;p&gt;The script maintains a log file to record all actions and a password file to store generated passwords securely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Input Validation&lt;/p&gt;

&lt;p&gt;Ensuring the script is provided with the correct input is crucial for its operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [ -z "$1" ]; then
    echo "Usage: $0 &amp;lt;name-of-text-file&amp;gt;"
    exit 1
fi

if [ ! -f "$1" ]; then
    echo "File $1 does not exist."
    exit 1
fi

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Directory and File Creation&lt;/p&gt;

&lt;p&gt;Creating necessary directories and setting permissions for secure operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /var/secure
touch $LOG_FILE
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate Password Function&lt;/p&gt;

&lt;p&gt;A simple function to generate random passwords.&lt;br&gt;
&lt;code&gt;generate_password() {&lt;br&gt;
    tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 12&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;User and Group Management&lt;/p&gt;

&lt;p&gt;The core logic to create users, assign groups, and handle existing users gracefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while IFS=';' read -r user groups; do
    user=$(echo "$user" | xargs)
    groups=$(echo "$groups" | xargs)

    if id "$user" &amp;amp;&amp;gt;/dev/null; then
        echo "User $user already exists. Skipping password setting." | tee -a $LOG_FILE
        continue
    fi

    if ! getent group "$user" &amp;gt;/dev/null; then
        groupadd "$user"
        echo "Group $user created." | tee -a $LOG_FILE
    fi

    useradd -m -g "$user" "$user"
    if [ $? -eq 0 ]; then
        echo "User $user created successfully." | tee -a $LOG_FILE
    else
        echo "Failed to create user $user." | tee -a $LOG_FILE
        continue
    fi

    if [ -n "$groups" ]; then
        IFS=',' read -ra group_array &amp;lt;&amp;lt;&amp;lt; "$groups"
        for group in "${group_array[@]}"; do
            group=$(echo "$group" | xargs)
            if ! getent group "$group" &amp;gt;/dev/null; then
                groupadd "$group"
                echo "Group $group created." | tee -a $LOG_FILE
            fi
            usermod -aG "$group" "$user"
            echo "User $user added to group $group." | tee -a $LOG_FILE
        done
    fi

    password=$(generate_password)
    echo "$user:$password" | chpasswd
    echo "$user,$password" &amp;gt;&amp;gt; $PASSWORD_FILE
    echo "Password for user $user set and stored securely." | tee -a $LOG_FILE

done &amp;lt; "$1"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conclusion&lt;br&gt;
Automating user management tasks using Bash scripts can significantly improve efficiency and accuracy in system operations. This guide and the accompanying script provide a robust solution for user creation, group assignment, and secure password management.&lt;/p&gt;

&lt;p&gt;For more information on DevOps and automation, check out these resources:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hng.tech/internship"&gt;HNG Internship&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hng.tech/"&gt;HNG Hire&lt;/a&gt;&lt;br&gt;
By following these steps, you can ensure a streamlined process for managing users in your development environment.&lt;/p&gt;

&lt;p&gt;link to my github: &lt;a href="https://github.com/Gbenga001/user_account_automation_with_bash"&gt;https://github.com/Gbenga001/user_account_automation_with_bash&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Developing a Reusable and Readable Bash Script for LAMP Stack Deployment</title>
      <dc:creator>Gbenga Akinbajo Okunniyi</dc:creator>
      <pubDate>Mon, 22 Apr 2024 18:43:05 +0000</pubDate>
      <link>https://dev.to/gbenga_okunniyi/developing-a-reusable-and-readable-bash-script-for-lamp-stack-deployment-3mk</link>
      <guid>https://dev.to/gbenga_okunniyi/developing-a-reusable-and-readable-bash-script-for-lamp-stack-deployment-3mk</guid>
      <description>&lt;p&gt;&lt;strong&gt;In the fast-paced world of system administration and DevOps, automation reigns supreme. Deploying a LAMP (Linux, Apache, MySQL, PHP) stack manually can be time-consuming and error-prone. Hence, crafting a reusable and readable Bash script for automating this process not only saves time but also ensures consistency and ease of maintenance for future deployments. Let's embark on a journey to develop a powerful Bash script that automates the deployment of a LAMP stack, including cloning a PHP application from GitHub, installing necessary packages, and configuring Apache web server and MySQL.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`#!/bin/bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Function to handle errors
&lt;/h1&gt;

&lt;p&gt;handle_error() {&lt;br&gt;
    echo "Error: $1" &amp;gt;&amp;amp;2&lt;br&gt;
    exit 1&lt;br&gt;
}&lt;/p&gt;

&lt;h1&gt;
  
  
  Update Linux system
&lt;/h1&gt;

&lt;p&gt;sudo apt update -y || handle_error "Failed to update the system."&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Apache web server
&lt;/h1&gt;

&lt;p&gt;sudo apt install apache2 -y || handle_error "Failed to install Apache web server."&lt;/p&gt;

&lt;h1&gt;
  
  
  Add PHP ondrej repository
&lt;/h1&gt;

&lt;p&gt;sudo add-apt-repository ppa:ondrej/php --yes || handle_error "Failed to add PHP repository."&lt;/p&gt;

&lt;h1&gt;
  
  
  Update repository again
&lt;/h1&gt;

&lt;p&gt;sudo apt update -y || handle_error "Failed to update repository."&lt;/p&gt;

&lt;h1&gt;
  
  
  Install PHP 8.2 and necessary extensions
&lt;/h1&gt;

&lt;p&gt;sudo apt install php8.2 php8.2-curl php8.2-dom php8.2-mbstring php8.2-xml php8.2-mysql zip unzip -y || handle_error "Failed to install PHP and extensions."&lt;/p&gt;

&lt;h1&gt;
  
  
  Enable rewrite module for Apache
&lt;/h1&gt;

&lt;p&gt;sudo a2enmod rewrite || handle_error "Failed to enable rewrite module for Apache."&lt;/p&gt;

&lt;h1&gt;
  
  
  Restart Apache server
&lt;/h1&gt;

&lt;p&gt;sudo systemctl restart apache2 || handle_error "Failed to restart Apache server."&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Composer globally
&lt;/h1&gt;

&lt;p&gt;cd /tmp || handle_error "Failed to change directory to /tmp."&lt;br&gt;
sudo curl -sS &lt;a href="https://getcomposer.org/installer"&gt;https://getcomposer.org/installer&lt;/a&gt; | sudo php -- --install-dir=/usr/local/bin --filename=composer || handle_error "Failed to install Composer globally."&lt;/p&gt;

&lt;h1&gt;
  
  
  Change directory to /var/www and clone Laravel repository
&lt;/h1&gt;

&lt;p&gt;if [ -d /var/www/laravel ]; then&lt;br&gt;
   echo "Deleting existing Laravel directory"&lt;br&gt;
   sudo rm -r /var/www/laravel&lt;br&gt;
else&lt;br&gt;
   echo "Creating Laravel directory"&lt;br&gt;
fi&lt;br&gt;
sudo mkdir /var/www/laravel&lt;br&gt;
sudo chown -R $USER:$USER /var/www/laravel&lt;br&gt;
cd /var/www/ || handle_error "Failed to change directory to /var/www/."&lt;br&gt;
sudo git clone &lt;a href="https://github.com/laravel/laravel.git"&gt;https://github.com/laravel/laravel.git&lt;/a&gt; laravel || handle_error "Failed to clone Laravel repository."&lt;/p&gt;

&lt;h1&gt;
  
  
  Set permissions
&lt;/h1&gt;

&lt;p&gt;sudo chown -R $USER:$USER /var/www/laravel || handle_error "Failed to set permissions."&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Composer dependencies
&lt;/h1&gt;

&lt;p&gt;cd /var/www/laravel || handle_error "Failed to change directory to /var/www/laravel."&lt;br&gt;
composer install --optimize-autoloader --no-dev --no-interaction || handle_error "Failed to install Composer dependencies."&lt;br&gt;
composer update --no-interaction || handle_error "Failed to update Composer dependencies."&lt;/p&gt;

&lt;h1&gt;
  
  
  Copy .env file and set permissions
&lt;/h1&gt;

&lt;p&gt;sudo cp .env.example .env || handle_error "Failed to copy .env file."&lt;br&gt;
sudo chown -R www-data:www-data storage bootstrap/cache || handle_error "Failed to set permissions."&lt;/p&gt;

&lt;h1&gt;
  
  
  Configure Apache Virtual Host
&lt;/h1&gt;

&lt;p&gt;sudo tee /etc/apache2/sites-available/latest.conf &amp;gt; /dev/null &amp;lt;
&lt;br&gt;
    ServerName localhost&lt;br&gt;
    DocumentRoot /var/www/laravel/public&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Directory /var/www/laravel&amp;gt;
    AllowOverride All
&amp;lt;/Directory&amp;gt;

ErrorLog \${APACHE_LOG_DIR}/laravel-error.log
CustomLog \${APACHE_LOG_DIR}/laravel-access.log combined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
EOF&lt;/p&gt;

&lt;h1&gt;
  
  
  Enable the new Virtual Host and disable the default one
&lt;/h1&gt;

&lt;p&gt;sudo a2ensite latest.conf || handle_error "Failed to enable new Virtual Host."&lt;br&gt;
sudo a2dissite 000-default.conf || handle_error "Failed to disable default Virtual Host."&lt;/p&gt;

&lt;h1&gt;
  
  
  Restart Apache server
&lt;/h1&gt;

&lt;p&gt;sudo systemctl restart apache2 || handle_error "Failed to restart Apache server."&lt;/p&gt;

&lt;h1&gt;
  
  
  Install MySQL server and client
&lt;/h1&gt;

&lt;p&gt;sudo apt install mysql-server mysql-client -y || handle_error "Failed to install MySQL server and client."&lt;/p&gt;

&lt;h1&gt;
  
  
  Start MySQL service
&lt;/h1&gt;

&lt;p&gt;sudo systemctl start mysql || handle_error "Failed to start MySQL service."&lt;/p&gt;

&lt;h1&gt;
  
  
  Update .env file with MySQL configuration
&lt;/h1&gt;

&lt;p&gt;sudo cp .env.example .env&lt;br&gt;
sudo chown -R $USER:$USER /var/www/laravel/.env&lt;br&gt;
echo "APP_URL=&lt;a href="http://localhost"&gt;http://localhost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DB_CONNECTION=mysql&lt;br&gt;
DB_HOST=127.0.0.1&lt;br&gt;
DB_PORT=3306&lt;br&gt;
DB_DATABASE=laravel&lt;br&gt;
DB_USERNAME=root&lt;br&gt;
DB_PASSWORD= " &amp;gt;&amp;gt; /var/www/laravel/.env&lt;/p&gt;

&lt;h1&gt;
  
  
  Generate Laravel application key
&lt;/h1&gt;

&lt;p&gt;sudo php artisan key:generate || handle_error "Failed to generate application key."&lt;/p&gt;

&lt;h1&gt;
  
  
  Create symbolic link for storage
&lt;/h1&gt;

&lt;p&gt;sudo php artisan storage:link || handle_error "Failed to create storage symbolic link."&lt;/p&gt;

&lt;h1&gt;
  
  
  Migrate database
&lt;/h1&gt;

&lt;p&gt;sudo php artisan migrate&lt;/p&gt;

&lt;h1&gt;
  
  
  Seed database
&lt;/h1&gt;

&lt;p&gt;sudo php artisan db:seed&lt;/p&gt;

&lt;h1&gt;
  
  
  Serve page
&lt;/h1&gt;

&lt;p&gt;sudo php artisan serve&lt;/p&gt;

&lt;h1&gt;
  
  
  Restart Apache server
&lt;/h1&gt;

&lt;p&gt;sudo systemctl restart apache2&lt;/p&gt;

&lt;p&gt;echo "Setup completed successfully!"`&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's break down what each section of this script accomplishes:&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Developing a Reusable and Readable Bash Script for Automated LAMP Stack Deployment</title>
      <dc:creator>Gbenga Akinbajo Okunniyi</dc:creator>
      <pubDate>Mon, 22 Apr 2024 18:42:26 +0000</pubDate>
      <link>https://dev.to/gbenga_okunniyi/developing-a-reusable-and-readable-bash-script-for-automated-lamp-stack-deployment-3a8g</link>
      <guid>https://dev.to/gbenga_okunniyi/developing-a-reusable-and-readable-bash-script-for-automated-lamp-stack-deployment-3a8g</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kydinpeapmt32njwie5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kydinpeapmt32njwie5.png" alt="Image description" width="800" height="449"&gt;&lt;/a&gt;Automating the deployment of a LAMP (Linux, Apache, MySQL, PHP) stack is a crucial task for any system administrator or DevOps engineer. In this guide, we'll walk through the creation of a powerful Bash script that automates the entire deployment process, from cloning a PHP application from GitHub to configuring Apache web server and MySQL. Our goal is to ensure ease of maintenance and future deployments by developing a script that is both reusable and readable.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Updating the System and Installing Apache
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update -y || handle_error "Failed to update the system."
sudo apt install apache2 -y || handle_error "Failed to install Apache web server."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We begin by updating the Linux system and installing the Apache web server. The -y flag is used to automatically confirm any prompts during the installation process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding PHP Repository and Installing PHP
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo add-apt-repository ppa:ondrej/php --yes || handle_error "Failed to add PHP repository."
sudo apt update -y || handle_error "Failed to update repository."
sudo apt install php8.2 php8.2-curl php8.2-dom php8.2-mbstring php8.2-xml php8.2-mysql zip unzip -y || handle_error "Failed to install PHP and extensions."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add the PHP repository maintained by Ondřej Surý and install PHP 8.2 along with necessary extensions required for our LAMP stack.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enabling Apache Modules and Restarting Apache
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo a2enmod rewrite || handle_error "Failed to enable rewrite module for Apache."
sudo systemctl restart apache2 || handle_error "Failed to restart Apache server."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We enable the rewrite module for Apache to allow for clean URL configuration and then restart the Apache server to apply the changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing Composer Globally
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer || handle_error "Failed to install Composer globally."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Composer, a dependency manager for PHP, is installed globally to facilitate dependency management for our PHP applications.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloning Laravel Application from GitHub
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /var/www/ || handle_error "Failed to change directory to /var/www/."
sudo git clone https://github.com/laravel/laravel.git laravel || handle_error "Failed to clone Laravel repository."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We navigate to the web root directory and clone a Laravel application from its GitHub repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuring Apache Virtual Host
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo tee /etc/apache2/sites-available/latest.conf &amp;gt; /dev/null &amp;lt;&amp;lt;EOF
&amp;lt;VirtualHost *:80&amp;gt;
    ServerName localhost
    DocumentRoot /var/www/laravel/public

    &amp;lt;Directory /var/www/laravel&amp;gt;
        AllowOverride All
    &amp;lt;/Directory&amp;gt;

    ErrorLog \${APACHE_LOG_DIR}/laravel-error.log
    CustomLog \${APACHE_LOG_DIR}/laravel-access.log combined
&amp;lt;/VirtualHost&amp;gt;
EOF




&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We configure a virtual host for our Laravel application, pointing Apache to the application's public directory and setting up error and access logs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enabling and Disabling Virtual Hosts
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo a2ensite latest.conf || handle_error "Failed to enable new Virtual Host."
sudo a2dissite 000-default.conf || handle_error "Failed to disable default Virtual Host."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We enable the newly configured virtual host while disabling the default one to ensure our Laravel application is served correctly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing MySQL Server and Client
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install mysql-server mysql-client -y || handle_error "Failed to install MySQL server and client."
sudo systemctl start mysql || handle_error "Failed to start MySQL service."


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MySQL server and client are installed, and the MySQL service is started to set up the database management system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Updating .env File with MySQL Configuration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo cp .env.example .env
sudo chown -R $USER:$USER /var/www/laravel/.env

echo "APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD= " &amp;gt;&amp;gt; /var/www/laravel/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We copy the example environment file, set appropriate ownership, and update it with MySQL configuration details.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generating Laravel Application Key and Creating Symbolic Link
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo php artisan key:generate || handle_error "Failed to generate application key."
sudo php artisan storage:link || handle_error "Failed to create storage symbolic link."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We generate a unique application key for Laravel and create a symbolic link for storage.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Migrating and Seeding Database
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo php artisan migrate
sudo php artisan db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Database migration and seeding are performed to set up the database schema and populate it with initial data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serving the Application
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we serve the Laravel application using the built-in PHP development server.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
By following this guide and developing a reusable and readable Bash script, one can automate the deployment of a LAMP stack with ease. This script ensures consistency, scalability, and ease of maintenance for future deployments. &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Follow-Up: Enhancing Automation with Ansible Playbooks and Cron Jobs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In our previous blog post, we explored the development of a robust Bash script for automating the deployment of a LAMP stack. Building upon that foundation, we will now leverage Ansible playbooks and cron jobs to further enhance our automation capabilities and ensure seamless management of our server infrastructure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ansible Playbook for Deployment&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ansible provides a powerful automation framework for orchestrating configuration management tasks across multiple servers. We'll start by creating an Ansible playbook that executes our Bash script on the slave node, ensuring consistent deployment across our server infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# deploy.yml

- hosts: slave
  tasks:
    - name: Transfer deployment script to slave node
      copy:
        src: /path/to/deploy.sh
        dest: /tmp/deploy.sh

    - name: Execute deployment script on slave node
      shell: /bin/bash /tmp/deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;hosts: Specifies the target host or group of hosts where the playbook tasks will be executed. In this case, we target the "slave" server.&lt;/li&gt;
&lt;li&gt;copy: Copies the deployment script from the control node to the specified destination on the slave node.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;shell: Executes the deployment script on the slave node using the Bash shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cron Job for Uptime Monitoring&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add the following line to the crontab file
0 0 * * * /usr/bin/uptime &amp;gt;&amp;gt; /var/log/server_uptime.log

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 0 * * *: Specifies the schedule for the cron job. In this case, the job runs every day at midnight (00:00).
/usr/bin/uptime: Executes the uptime command to retrieve information about the server's uptime.
&amp;gt;&amp;gt; /var/log/server_uptime.log: Appends the output of the uptime command to a log file for record-keeping and monitoring.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution and Verification&lt;br&gt;
Executing Ansible Playbook:&lt;br&gt;
Run the Ansible playbook (ansible-playbook deploy.yml) from the control node.&lt;br&gt;
Verify successful execution by accessing the PHP application through the slave node's IP address.&lt;/p&gt;

&lt;p&gt;Cron Job Verification:&lt;br&gt;
Check the /var/log/server_uptime.log file on the slave node to ensure that uptime logs are being recorded as expected.&lt;br&gt;
Tail the log file (tail -f /var/log/server_uptime.log) to monitor real-time uptime updates.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
By incorporating Ansible playbooks and cron jobs into my automation workflow, I have further streamlined the deployment process and implemented proactive monitoring for server uptime. These tools enable one&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzn4l0uk8f3rdewkotfl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzn4l0uk8f3rdewkotfl.png" alt="Image description" width="800" height="449"&gt;&lt;/a&gt; to maintain a reliable and efficient server infrastructure while reducing manual intervention.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
      <category>automation</category>
    </item>
    <item>
      <title>Title: Bridging the Gap: My Journey into Cloud Engineering at Altschool Africa</title>
      <dc:creator>Gbenga Akinbajo Okunniyi</dc:creator>
      <pubDate>Tue, 20 Feb 2024 11:32:42 +0000</pubDate>
      <link>https://dev.to/gbenga_okunniyi/title-bridging-the-gap-my-journey-into-cloud-engineering-at-altschool-africa-3dll</link>
      <guid>https://dev.to/gbenga_okunniyi/title-bridging-the-gap-my-journey-into-cloud-engineering-at-altschool-africa-3dll</guid>
      <description>&lt;p&gt;In the dynamic landscape of technology, embarking on a journey into the realms of cloud engineering can be both exhilarating and challenging. My personal odyssey at Altschool Africa during this second semester has been nothing short of transformative, particularly as I delved into the intricacies of Linux, Bash scripts, and the foundations of web development. What makes this venture truly remarkable is the backdrop of my unconventional transition – from a History and International Studies background, navigating a 9-5 job, and embarking on a journey into the world of coding with zero programming knowledge.&lt;/p&gt;

&lt;p&gt;Embracing the Unknown: A New Chapter Unfolds&lt;/p&gt;

&lt;p&gt;As someone with a background steeped in humanities, my foray into cloud engineering felt like a leap into the unknown. The semester opened with the vast universe of Linux, a powerful and intricate operating system that would serve as the canvas for my cloud engineering endeavors. The command line, once an alien landscape, gradually became my playground as I learned to navigate, execute commands, and understand the underlying architecture of systems.&lt;/p&gt;

&lt;p&gt;From Hello World to the Cloud: A Novice's Tale&lt;/p&gt;

&lt;p&gt;The journey commenced with the humble "Hello World." For someone unfamiliar with programming languages, this initial step felt like conquering a mountain. Yet, it was this very ascent that fueled my motivation. Starting with Bash scripts, I began to decipher the syntax and logic behind every line of code. The thrill of seeing my first "Hello World" script run successfully was more than a technical triumph – it was a testament to persistence and the joy of overcoming the challenges of the unknown.&lt;/p&gt;

&lt;p&gt;Balancing Act: A Symphony of Learning and Daily Grind&lt;/p&gt;

&lt;p&gt;One might wonder how a History and International Studies graduate with a full-time job found the bandwidth for learning cloud engineering. The answer lies in the delicate art of balance. My daily routine, comprising the demands of a 9-5 job, metamorphosed into a symphony where evenings became sacred spaces for learning. The commitment to growth became a compass guiding me through the intricacies of HTML, CSS, and Javascript – languages I had never imagined myself mastering.&lt;/p&gt;

&lt;p&gt;Empowering Future Vistas: A Motivational Beacon&lt;/p&gt;

&lt;p&gt;What began as an exploration into the world of Linux and Bash scripts evolved into a broader narrative of self-discovery. The journey is more than a conquest of technical skills; it's a testament to the human spirit's capacity to adapt, learn, and thrive in uncharted territories. To my fellow learners, I offer this as a beacon of inspiration – a reminder that the pursuit of knowledge is not confined to academic backgrounds or predetermined paths. The cloud engineering frontier welcomes diversity, and every step, no matter how small, propels us towards empowerment.&lt;/p&gt;

&lt;p&gt;Conclusion: The Unwritten Chapters Await&lt;/p&gt;

&lt;p&gt;As this semester unfolds, I find myself standing at the intersection of my past and the unwritten chapters of the future. Altschool Africa has not just equipped me with technical skills but has fostered a mindset of perpetual learning and adaptation. The odyssey continues, and with each line of code, I am not just scripting programs but rewriting my narrative. May this account serve as a testament that every individual possesses the potential to carve their niche in the ever-evolving world of technology. Let the next chapter begin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t26il8ypfdstkl1uups.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t26il8ypfdstkl1uups.jpg" alt="Image description" width="800" height="1132"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
