Creating the infrastructure for a secure 3-tier application on Azure
main.tf file :
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "appservice-rg"
location = "francecentral"
}
resource "azurerm_virtual_network" "vnet" {
name = "vnet"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "integrationsubnet" {
name = "integrationsubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
}
}
}
resource "azurerm_subnet" "endpointsubnet" {
name = "endpointsubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.2.0/24"]
private_endpoint_network_policies_enabled = true
}
resource "azurerm_service_plan" "appserviceplan" {
name = "appserviceplan"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
os_type = "Windows"
sku_name = "S1"
}
resource "azurerm_windows_web_app" "frontwebapp" {
name = "frontend-kk"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
service_plan_id = azurerm_service_plan.appserviceplan.id
site_config {}
app_settings = {
"WEBSITE_DNS_SERVER" = "168.63.129.16",
"BACKEND_URL" = "http://${azurerm_private_dns_zone_virtual_network_link.dnszonelink.private_dns_zone_name}/api/message"
}
}
resource "azurerm_app_service_virtual_network_swift_connection" "vnetintegrationconnection" {
app_service_id = azurerm_windows_web_app.frontwebapp.id
subnet_id = azurerm_subnet.integrationsubnet.id
}
resource "azurerm_windows_web_app" "backwebapp" {
name = "backend-kk"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
service_plan_id = azurerm_service_plan.appserviceplan.id
site_config {}
}
resource "azurerm_private_dns_zone" "dnsprivatezone" {
name = "privatelink.azurewebsites.net"
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "dnszonelink" {
name = "dnszonelink"
resource_group_name = azurerm_resource_group.rg.name
private_dns_zone_name = azurerm_private_dns_zone.dnsprivatezone.name
virtual_network_id = azurerm_virtual_network.vnet.id
}
resource "azurerm_private_endpoint" "privateendpoint" {
name = "backwebappprivateendpoint"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.endpointsubnet.id
private_dns_zone_group {
name = "privatednszonegroup"
private_dns_zone_ids = [azurerm_private_dns_zone.dnsprivatezone.id]
}
private_service_connection {
name = "privateendpointconnection"
private_connection_resource_id = azurerm_windows_web_app.backwebapp.id
subresource_names = ["sites"]
is_manual_connection = false
}
}
resource "random_pet" "azurerm_mssql_server_name" {
prefix = "sql"
}
resource "azurerm_mssql_server" "server" {
name = random_pet.azurerm_mssql_server_name.id
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
version = "12.0"
administrator_login = "sqladmin"
administrator_login_password = "ENTER THE PASSWORD"
}
# MSSQL Database
resource "azurerm_mssql_database" "sqldatabase" {
name = "appdatabase"
server_id = azurerm_mssql_server.server.id
collation = "SQL_Latin1_General_CP1_CI_AS"
license_type = "LicenseIncluded"
max_size_gb = 10
sku_name = "S0"
zone_redundant = false
}
# Network Security Group for MSSQL Database
resource "azurerm_network_security_group" "sqlnsg" {
name = "sqlnsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Network Security Rule to allow SQL traffic
resource "azurerm_network_security_rule" "sqlrule" {
name = "SQLTraffic"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "1433"
source_address_prefix = "VirtualNetwork"
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.rg.name
network_security_group_name = azurerm_network_security_group.sqlnsg.name
}
# Associate NSG to the Subnet
resource "azurerm_subnet_network_security_group_association" "sqlsubnetnsgassociation" {
subnet_id = azurerm_subnet.endpointsubnet.id
network_security_group_id = azurerm_network_security_group.sqlnsg.id
}
Then we have to follow the below commands :
terraform init
terraform plan
terraform apply
On doing this, the Terraform code provisions a secure 3-tier application infrastructure on Azure. It creates a resource group, virtual network with two subnets, an app service plan, frontend and backend web apps, a private DNS zone, and a private endpoint for the backend app. It also sets up an MSSQL server and database, along with a network security group and rules to allow SQL traffic within the virtual network.