In this blog, I'll guide you through the process of creating a secure, private infrastructure on Azure using Terraform. We will utilize custom modules to deploy various Azure services, ensuring that all components are privately accessible. This setup includes a private AKS cluster, ACR, private endpoints, and more. By the end, you'll have a robust and secure infrastructure ready for your applications.
Before you begin, make sure you have the following installed:
We have structured the repository using custom Terraform modules for each Azure service. This modular approach makes the infrastructure scalable and easier to manage. Clone the repository to get started:
git clone https://github.com/prometheantechws/Terraform-Azure-Infra.gitcd Terraform-Azure-Infra
Before running Terraform, you need to update the main.tf
and terraform.tfvars
files with your specific configurations.
main.tf: This is where we define the main structure of our infrastructure.
terraform.tfvars: This file contains variable definitions that Terraform will use during execution.
Make sure to change the values as per your requirements.
Our infrastructure is built using the following custom modules:
Each module is defined in the modules
directory. Let's walk through the setup of each module.
The Resource Group is the container for all the resources in our Azure deployment.
module "RG" {source = "../../modules/RG"resource_group_name = var.resource_group_namelocation = var.location# tags = var.RG_tags}
The VNet will host our subnets for different services.
module "Vnet" {source = "../../modules/Vnet"resource_group_name = module.RG.RG_namelocation = var.locationdepends_on = [module.RG]vnets = var.virtual_networks}
To allow communication between VNets.
module "vnet_peering" {source = "../../modules/Vnet-peering"depends_on = [module.Vnet]peerings = {peering1 = {name = var.peering_nameresource_group_name = module.RG.RG_namevnet1_name = module.Vnet.vnet_names["vnet1"]vnet2_id = module.Vnet.vnet_ids["vnet2"]vnet2_name = module.Vnet.vnet_names["vnet2"]vnet1_id = module.Vnet.vnet_ids["vnet1"]allow_forwarded_traffic = trueallow_gateway_transit = falseuse_remote_gateways = falseallow_virtual_network_access = true}}}
A private AKS cluster for running your Kubernetes workloads.
module "AKS" {source = "../../modules/AKS-Private-Cluster"depends_on = [module.RG,module.Vnet]aks_cluster_name = var.aks_cluster_nameresource_group_name = module.RG.RG_namelocation = var.locationdns_prefix = var.dns_prefixkubernetes_version = var.kubernetes_versiondefault_node_pool_name = var.default_node_pool_namenode_count = var.node_countvm_size = var.vm_sizeaks_vnet_subnet_id = data.azurerm_subnet.aks_subnet.iddefault_node_pool_auto_scaling = var.default_node_pool_auto_scalingdefault_node_pool_max_count = var.default_node_pool_max_countdefault_node_pool_min_count = var.default_node_pool_min_countdefault_node_pool_zones = var.default_node_pool_zonesidentity_type = var.identity_typesku_tier = var.sku_tiernetwork_plugin = var.network_pluginnetwork_policy = var.network_policyload_balancer_sku = var.load_balancer_skuoutbound_type = var.outbound_typedns_service_ip = var.dns_service_ipservice_cidr = var.service_cidrprivate_cluster_enabled = var.private_cluster_enabledrole_based_access_control_enabled = var.role_based_access_control_enabledspoke_vnet_id = module.Vnet.vnet_ids["vnet2"]spoke_subnet_id = module.Vnet.subnet_ids["vnet2"]["snet-aks-stage"]acr_id = module.ACR.acr_idkv_id = module.key_vault.kv_id############################# HUB VNET LINK #############################virtual_network_links = {link1 = {name = "vnetl-hub"virtual_network_id = module.Vnet.vnet_ids["vnet1"]registration_enabled = false}}#############################Private DNS ZONE#############################node_pools = {userpool-1 = {name = "npuserpool"vm_size = "Standard_E2as_v5"node_count = 1max_pods = 30mode = "User"os_disk_size_gb = 100os_type = "Linux"custom_ca_trust_enabled = falseenable_auto_scaling = trueenable_host_encryption = falseenable_node_public_ip = falsefips_enabled = falsemin_count = 1max_count = 3node_labels = {}node_taints = []vnet_subnet_id = data.azurerm_subnet.aks_subnet.idzones = ["1", "2", "3"]}}}
A private container registry for storing Docker images.
module "ACR" {source = "../../modules/Azure-Container-Registries"depends_on = [module.RG,module.Vnet]acr_name = var.acr_nameresource_group_name = module.RG.RG_namelocation = var.locationsku = var.skuadmin_enabled = var.admin_enabled}
Private Endpoints for secure connections.
module "acr_private_endpoints" {source = "../../modules/Azure-Private-Endpoints"depends_on = [module.RG,module.Vnet,module.ACR]resource_group_name = module.RG.RG_namelocation = var.locationvnet_name = module.Vnet.vnet_names["vnet1"]subnet_name = module.Vnet.subnet_names["vnet1"][1]private_endpoint_name = var.acr_private_endpoint_nameprivate_service_connections = {acr = {name = "acr-link"private_connection_resource_id = module.ACR.acr_idsubresource_names = ["registry"]is_manual_connection = false}}private_dns_zone_group_name = "private-dns-zone-group"private_dns_zone_ids = [module.acr_private_dns_zone.dns_zone_id]}
For private DNS resolution.
module "acr_private_dns_zone" {source = "../../modules/Private-DNS-Zone"depends_on = [module.RG,module.Vnet]dns_zone_name = var.acr_dns_zone_nameresource_group_name = module.RG.RG_namevirtual_network_links = {link1 = {name = "pl-hub-vnet-link"virtual_network_id = module.Vnet.vnet_ids["vnet1"]registration_enabled = false}link2 = {name = "pl-spoke-vnet-link"virtual_network_id = module.Vnet.vnet_ids["vnet2"]registration_enabled = false}}}
A Key Vault for secure storage of secrets.
module "key_vault" {source = "../../modules/Key-Vaults"depends_on = [module.RG,module.Vnet]resource_group_name = module.RG.RG_namelocation = var.locationkey_vault_name = var.key_vault_namesku_name = var.key_vault_locationsoft_delete_retention_days = var.key_vault_soft_delete_retention_dayspurge_protection_enabled = var.key_vault_purge_protection_enabled# KV_ACCESS_POLICYkey_vault_dependency = [module.AKS]key_vault_id = module.key_vault.kv_idtenant_id = module.key_vault.kv_tenanet_idobject_id = module.AKS.aks_client_idkey_permissions = ["Get"]secret_permissions = ["Get"]certificate_permissions = ["Get"]}
Deploying Linux and Windows VMs.
module "linux_vm" {source = "../../modules/Linux-Virtual-Machines"depends_on = [module.RG,module.Vnet]create_public_ip = falseresource_group_name = module.RG.RG_namelocation = var.locationvnet_name = module.Vnet.vnet_names["vnet1"]subnet_name = module.Vnet.subnet_names["vnet1"][0]vm_size = var.linux_vm_sizevm_admin_username = var.linux_vm_admin_usernamevm_admin_password = var.linux_vm_admin_passwordvm_name = var.linux_vm_namevm_type = var.linux_vm_type # or "Windows"subnet_id = module.Vnet.subnet_ids["vnet1"]["snet-shared-stage"]}module "windows_vm" {source = "../../modules/Windows-Virtual-Machines"resource_group_name = module.RG.RG_namelocation = var.locationvnet_name = module.Vnet.vnet_names["vnet1"]subnet_name = module.Vnet.subnet_names["vnet1"][0]vm_size = var.windows_vm_sizevm_admin_username = var.windows_vm_admin_usernamevm_admin_password = var.windows_vm_admin_passwordvm_name = var.windows_vm_namevm_type = var.windows_vm_type # or "Windows"subnet_id = module.Vnet.subnet_ids["vnet1"]["snet-shared-stage"]}
A storage account for data storage needs.
module "storage_account" {source = "../../modules/Storage-Accounts"depends_on = [module.RG,module.Vnet]resource_group_name = module.RG.RG_namelocation = var.locationstorage_account_name = var.storage_account_nameaccount_tier = var.account_tieraccount_replication_type = var.account_replication_typepublic_network_access_enabled = var.public_network_access_enabled}
Once you have updated the configuration files with your details, run the following commands to deploy the infrastructure:
terraform initterraform validateterraform planterraform apply
Terraform will show you a plan of the resources it will create. Review the plan carefully and then apply it to create the resources.
In this blog, we set up a private infrastructure on Azure using Terraform and custom modules. This modular approach helps maintain clean and manageable code, making it easier to scale and manage the infrastructure.
Feel free to clone the repository and modify it as per your needs. Happy coding!
Thank you for reading our comprehensive guide on "Building Private Azure Infrastructure with Terraform" We hope you found it insightful and valuable. If you have any questions, need further assistance, or are looking for expert support in setting up and managing your Azure infrastructure, our team is here to help!
Reach out to us for Your Azure Infrastructure Needs:
🌐 Website: https://www.prometheantech.in
📧 Email: [email protected]
Happy Terraforming!
Copyright © 2024 PrometheanTech. All Rights Reserved.