- π About the Project
- π» Getting Started
- π§ Customizing Variables
- βοΈ Remote Terraform State in Azure
- π₯ Authors
- π Future Features
- π€ Contributing
- βοΈ Show your support
- π Acknowledgements
- β FAQ
- π License
This project automates the provisioning and deployment of a scalable cloud application on Microsoft Azure. It uses Terraform to create infrastructure, and Ansible to configure services like a backend API running on 2 VMs behind a Load Balancer, connected to an Azure MySQL database, along with a frontend deployed on Azure Web App.
Architecture Diagram
## π Built WithInfrastructure as Code
Configuration Management
Cloud Platform
Database
Deployment Targets
- Azure Virtual Machines
- Azure Load Balancer
- Azure App Service (Web App)
- π§ Automated infrastructure provisioning with Terraform
- π¦ Service configuration and app deployment using Ansible
- π MySQL database initialized via Ansible using
ansible/files/mysql/movie_db.sql - π Scalable API on 2 Azure VMs behind a Load Balancer
- πΎ Managed Azure MySQL integration
- π Web frontend deployed using Azure Web App
- π Service Principal authentication using Client Secret
- βοΈ Fully automated deployment workflow with CI/CD integration
- ποΈ End-to-end Terraform deployment from scratch included in workflow
- π§Ή Automated environment teardown using
terraform-destroy.yml - πΈ Uses Azure Web App F1 Free Tier for cost-effective deployment
To get a local copy up and running, follow these instructions.
Most dependencies are installed automatically in the GitHub Actions workflow. However, for local development or debugging, ensure you have the following:
- π₯οΈ Azure CLI (
az) - π¦ Terraform β₯ 1.5
- βοΈ Ansible β₯ 2.15
- π SSH key pair for accessing virtual machines
- π¦ Node.js β₯ 14 and npm (required for both frontend and backend)
- π
ziputility (used to package the frontend app) - βοΈ Azure Service Principal credentials (used by the workflow):
ARM_CLIENT_IDARM_CLIENT_SECRETARM_TENANT_IDARM_SUBSCRIPTION_ID
- π‘ (Optional) GitHub CLI (
gh) β useful for managing secrets or manually triggering workflows
# Clone this repository
git clone https://github.com/NeckerFree/azure-fullstack-automation.git
cd azure-fullstack-automationcreate a file
Infrastructure provisioning is fully automated and triggered via GitHub Actions on every push or pull request to the master branch.
- Terraform is initialized and executed within the workflow using predefined variables.
- The deployment includes:
- A MySQL database on Azure
- A Load Balancer with 2 backend VMs
- Network and security resources
- The entire infrastructure is provisioned from scratch via
terraform.yml.
Once the infrastructure is up, Ansible playbooks are automatically triggered within the same CI/CD workflow to:
- Configure the VMs with the required packages
- Deploy the Node.js API to both backend nodes
- Apply application settings
- Validate MySQL schema creation and data population
This configuration is handled through the deploy-api.yml GitHub Actions workflow.
- π― Trigger: Every push or pull request to
masterkicks off a full deployment pipeline. - π API is publicly reachable via the Load Balancerβs IP address.
- π» Frontend is deployed to Azure Web App using the F1 Free Tier.
- π Secure integration between services via environment variables and Azure-managed credentials.
- 𧨠A separate
terraform-destroy.ymlworkflow is available to automatically destroy all infrastructure when needed.
You can modify the following variables to adapt the deployment to your needs. These are defined in the Terraform configuration files:
allowed_ssh_ip = "xxx.xxx.xxx.xxx/32" # IP allowed to access VMs via SSH
mysql_user = "mysqladmin" # MySQL admin user
mysql_admin_password = "Sec#reP@ssword123!" # MySQL admin passwordvariable "location" {
default = "westus2" # Azure region to deploy resources
}
variable "admin_username" {
default = "myadminuser" # Admin username for virtual machines
}
variable "lb_api_port" {
default = 8080 # API port exposed by Load Balancer
}Terraform uses remote state storage to persist infrastructure state across executions and team members.
This project stores the Terraform state file (terraform.tfstate) securely in an Azure Storage Account using a backend configuration like the following:
terraform {
backend "azurerm" {
resource_group_name = "my-resource-group"
storage_account_name = "myterraformstate"
container_name = "tfstate"
key = "infrastructure.tfstate"
}
}π€ Elio CortΓ©s
- GitHub: @NeckerFree
- Twitter: @ElioCortesM
- LinkedIn: elionelsoncortes
- Enable autoscaling for the API tier
- Implement managed identity-based DB auth
Contributions, issues, and feature requests are welcome!
Feel free to open an issue, or request features.
If you like this project, please βοΈ the repository and share it with others!
- Microsoft Azure documentation
- Ansible Azure Collection contributors
- HashiCorp Terraform Modules
- devops-rampup β Backend & frontend prototype used as base for this project
- EPAM DevOps Campus β Cloud and DevOps learning program
- ChatGPT β Assistance in automation, CI/CD, and documentation
- DeepSeek β Assistance in automation, CI/CD, and documentation
Secrets are securely stored as GitHub Actions secrets and injected at runtime into the workflows.
Yes! You can test locally using terraform plan and ansible-playbook in dry-run mode before committing changes.
By default, all resources are deployed to the westus2 Azure region. You can change this in infra/variables.tf.
You can run the terraform-destroy.yml GitHub Actions workflow to safely destroy the provisioned infrastructure.
The Azure MySQL database is provisioned with Terraform and initialized using movie_db.sql from Ansible.
The frontend is hosted on Azure Web App. The exact URL depends on the generated Azure App Service name. Check the Azure Portal or output logs.
This project is licensed under the MIT License.









