This project demonstrates how to deploy a web server on Azure Virtual Machine with Apache2 and MySQL, both manually and using Terraform. The setup includes a sample PHP website that connects to MySQL database.
- Overview
- Prerequisites
- Project Structure
- Method 1: Terraform Deployment
- Method 2: Manual Deployment
- Testing the Setup
- Accessing the Website
- Troubleshooting
- Cleanup
- Security Considerations
This project sets up:
- Azure Virtual Machine (Ubuntu 22.04 LTS)
- Apache2 web server
- MySQL database server
- PHP with MySQL support
- Sample website with database connectivity test
- Complete User Management System with CRUD operations (Create, Read, Update, Delete)
This project now includes a full-featured CRUD application for managing users:
- β Create: Add new users via web form
- β Read: View all users in a formatted table
- β Update: Edit existing user information
- β Delete: Remove users with confirmation dialog
- β Modern UI: Responsive design with gradient backgrounds
- β Statistics Dashboard: Real-time user count and database status
New Pages:
add_user.php- Add new usersmanage_users.php- View and manage all usersedit_user.php- Edit existing usersdelete_user.php- Delete users
π Documentation:
- Azure account with an active subscription
- SSH key pair (will be generated if not exists)
- Azure CLI
- Basic knowledge of Linux commands
AzureVM-Apache2-MYSQL/
βββ terraform/
β βββ main.tf # Main Terraform configuration
β βββ variables.tf # Variable definitions
β βββ outputs.tf # Output values
β βββ cloud-init.yaml # Cloud-init configuration
β βββ terraform.tfvars.example # Example variables file
βββ scripts/
β βββ create_azure_vm.sh # Azure VM creation script (CLI)
β βββ install_apache_mysql.sh # Apache2 & MySQL installation
β βββ configure_mysql.sh # MySQL configuration
β βββ deploy_website.sh # Website deployment
βββ website/
β βββ index.php # Main page
β βββ db_test.php # Database test page
β βββ info.php # PHP info page
βββ README.md # This file
-
Navigate to the terraform directory:
cd terraform -
Create terraform.tfvars file:
cp terraform.tfvars.example terraform.tfvars
-
Edit terraform.tfvars with your values:
nano terraform.tfvars
Example content:
resource_group_name = "rg-webserver-demo" location = "East US" prefix = "webserver" environment = "Development" vm_size = "Standard_B2s" admin_username = "azureuser" ssh_public_key_path = "~/.ssh/id_rsa.pub" mysql_root_password = "YourSecurePassword123!"
az loginterraform initterraform planterraform applyType yes when prompted to confirm.
terraform outputYou'll see output like:
public_ip_address = "20.X.X.X"
ssh_command = "ssh azureuser@20.X.X.X"
website_url = "http://20.X.X.X"
Cloud-init will automatically install and configure everything. Wait about 5-10 minutes, then check:
# SSH into the VM
ssh azureuser@<PUBLIC_IP>
# Check if services are running
sudo systemctl status apache2
sudo systemctl status mysql
# Exit the VM
exitOpen your browser and navigate to:
- Main page:
http://<PUBLIC_IP> - Database test:
http://<PUBLIC_IP>/db_test.php - PHP info:
http://<PUBLIC_IP>/info.php
-
Navigate to the scripts directory:
cd scripts -
Make the script executable:
chmod +x create_azure_vm.sh
-
Login to Azure:
az login
-
Run the VM creation script:
./create_azure_vm.sh
This will:
- Create a resource group
- Set up virtual network and subnet
- Configure network security group (NSG) with rules for SSH, HTTP, HTTPS
- Create public IP address
- Create and configure the VM
-
Note the output: Save the public IP address displayed at the end.
ssh azureuser@<PUBLIC_IP>-
Copy the installation scripts to the VM:
From your local machine:
scp install_apache_mysql.sh azureuser@<PUBLIC_IP>:~/ scp configure_mysql.sh azureuser@<PUBLIC_IP>:~/ scp deploy_website.sh azureuser@<PUBLIC_IP>:~/
-
SSH into the VM:
ssh azureuser@<PUBLIC_IP>
-
Make scripts executable:
chmod +x install_apache_mysql.sh configure_mysql.sh deploy_website.sh
-
Run the installation script:
sudo ./install_apache_mysql.sh
This will:
- Update system packages
- Install Apache2
- Install MySQL Server
- Install PHP and required modules
- Enable and start services
sudo ./configure_mysql.shWhen prompted:
- Enter a secure MySQL root password
- Confirm the password
This will:
- Set MySQL root password
- Create database
webdb - Create user
webuserwith passwordwebpass123 - Create sample
userstable with test data - Secure MySQL installation
sudo ./deploy_website.shThis will:
- Backup existing website files
- Deploy sample PHP website
- Set proper permissions
- Display access URLs
Open your browser and navigate to:
- Main page:
http://<PUBLIC_IP> - Database test:
http://<PUBLIC_IP>/db_test.php - PHP info:
http://<PUBLIC_IP>/info.php
# Check Apache status
sudo systemctl status apache2
# Test configuration
sudo apache2ctl configtest
# Check if Apache is listening
sudo netstat -tulpn | grep :80# Login to MySQL
sudo mysql -u root -p
# Show databases
SHOW DATABASES;
# Use webdb
USE webdb;
# Show tables
SHOW TABLES;
# Query users
SELECT * FROM users;
# Exit MySQL
EXIT;# Check PHP version
php -v
# Test PHP modules
php -m | grep mysql# Test from VM
curl http://localhost
# Test from outside (from your local machine)
curl http://<PUBLIC_IP>After deployment, you can access:
-
Homepage -
http://<PUBLIC_IP>/- Displays server information
- Shows PHP version
- Links to test pages
-
Database Test -
http://<PUBLIC_IP>/db_test.php- Tests MySQL connectivity
- Displays users from database
- Shows connection details
-
PHP Info -
http://<PUBLIC_IP>/info.php- Complete PHP configuration
- Loaded modules
- System information
Check firewall rules:
# On Azure portal, verify NSG rules allow port 80
az network nsg rule list --resource-group rg-webserver-demo --nsg-name webserver-nsg --output tableCheck Apache status:
sudo systemctl status apache2
sudo journalctl -u apache2 -n 50Check MySQL status:
sudo systemctl status mysqlVerify database and user:
sudo mysql -u root -p
SHOW DATABASES;
SELECT user, host FROM mysql.user WHERE user='webuser';Check credentials in db_test.php:
cat /var/www/html/db_test.php | grep -A 5 "servername"Verify PHP is installed:
php -vCheck Apache PHP module:
apache2ctl -M | grep phpRestart Apache:
sudo systemctl restart apache2Fix file permissions:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/htmlVerify NSG rule for SSH:
az network nsg rule show \
--resource-group rg-webserver-demo \
--nsg-name webserver-nsg \
--name Allow-SSH# Apache error logs
sudo tail -f /var/log/apache2/error.log
# Apache access logs
sudo tail -f /var/log/apache2/access.log
# MySQL logs
sudo tail -f /var/log/mysql/error.log
# System logs
sudo journalctl -xecd terraform
terraform destroyType yes when prompted.
# Delete the entire resource group
az group delete --name rg-webserver-demo --yes --no-wait
# Or delete individual resources
az vm delete --resource-group rg-webserver-demo --name webserver-vm --yes
az network nic delete --resource-group rg-webserver-demo --name webserver-nic
az network public-ip delete --resource-group rg-webserver-demo --name webserver-publicip
az network nsg delete --resource-group rg-webserver-demo --name webserver-nsg
az network vnet delete --resource-group rg-webserver-demo --name webserver-vnet-
MySQL Password:
- Change the default MySQL root password
- Use strong passwords for database users
- Never commit passwords to version control
-
SSH Access:
- Consider restricting SSH access to your IP only
- Use SSH keys instead of passwords
- Disable root login via SSH
-
Network Security:
- Restrict MySQL port (3306) access in production
- Consider using Azure Private Link for database
- Enable HTTPS (SSL/TLS) for production websites
-
Regular Updates:
sudo apt update sudo apt upgrade -y
-
Firewall Configuration:
# Enable UFW firewall sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable
- Use Azure Key Vault for storing secrets
- Enable Azure Disk Encryption for VM disks
- Configure Azure Backup for VM
- Set up Azure Monitor for logging and alerts
- Use Managed Identities for Azure service authentication
- Implement SSL/TLS with Let's Encrypt
- Azure Virtual Machines Documentation
- Apache2 Documentation
- MySQL Documentation
- Terraform Azure Provider
- Azure CLI Reference
MySQL Database:
- Database:
webdb - Username:
webuser - Password:
webpass123 - Root Password: (set during configuration)
terraform init # Initialize Terraform
terraform plan # Preview changes
terraform apply # Apply changes
terraform destroy # Destroy infrastructure
terraform output # Show outputs
terraform fmt # Format configuration files
terraform validate # Validate configurationaz login # Login to Azure
az account list # List subscriptions
az account set --subscription "<NAME>" # Set subscription
az group list # List resource groups
az vm list --output table # List VMs
az vm start --resource-group <RG> --name <VM> # Start VM
az vm stop --resource-group <RG> --name <VM> # Stop VM
az vm show --resource-group <RG> --name <VM> # Show VM detailssudo systemctl status apache2 # Check Apache status
sudo systemctl restart apache2 # Restart Apache
sudo systemctl status mysql # Check MySQL status
sudo systemctl restart mysql # Restart MySQLAfter completing this project, you will have learned:
- How to deploy Azure Virtual Machines using Terraform and Azure CLI
- How to configure network security groups and firewall rules
- How to install and configure Apache2 web server
- How to set up MySQL database server
- How to deploy PHP applications
- How to use cloud-init for automated configuration
- Infrastructure as Code (IaC) best practices
Feel free to submit issues, fork the repository, and create pull requests for any improvements.
This project is licensed under the MIT License - feel free to use it for learning and development purposes.
Created as a demonstration project for Azure VM deployment with Apache2 and MySQL.
Happy Deploying! π