|
#not use this! instead exist now 2 files as phases! |
|
terraform { |
|
required_providers { |
|
azurerm = { |
|
source = "hashicorp/azurerm" |
|
version = ">= 3.65.0" |
|
} |
|
helm = { |
|
source = "hashicorp/helm" |
|
version = "~> 2.0" |
|
} |
|
kubernetes = { |
|
source = "hashicorp/kubernetes" |
|
version = "~> 2.0" |
|
} |
|
} |
|
required_version = ">= 1.0.0" |
|
} |
|
|
|
provider "azurerm" { |
|
features {} |
|
subscription_id = var.subscription_id |
|
} |
|
|
|
provider "helm" { |
|
kubernetes { |
|
host = azurerm_kubernetes_cluster.aks.kube_config[0].host |
|
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_certificate) |
|
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_key) |
|
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].cluster_ca_certificate) |
|
} |
|
} |
|
|
|
provider "kubernetes" { |
|
host = azurerm_kubernetes_cluster.aks.kube_config[0].host |
|
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_certificate) |
|
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_key) |
|
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].cluster_ca_certificate) |
|
} |
|
|
|
# Resource Group |
|
resource "azurerm_resource_group" "main" { |
|
name = var.resource_group_name |
|
location = var.location |
|
tags = { |
|
Environment = var.environment |
|
} |
|
} |
|
|
|
# Log Analytics Workspace for Monitoring |
|
resource "azurerm_log_analytics_workspace" "main" { |
|
name = var.log_analytics_workspace_name |
|
location = azurerm_resource_group.main.location |
|
resource_group_name = azurerm_resource_group.main.name |
|
sku = "PerGB2018" |
|
retention_in_days = var.log_retention_in_days |
|
} |
|
|
|
# Backup Vault |
|
resource "azurerm_recovery_services_vault" "main" { |
|
name = var.backup_vault_name |
|
location = azurerm_resource_group.main.location |
|
resource_group_name = azurerm_resource_group.main.name |
|
sku = "Standard" |
|
soft_delete_enabled = true |
|
} |
|
|
|
# Virtual Network |
|
resource "azurerm_virtual_network" "main" { |
|
name = "${var.cluster_name}-vnet" |
|
address_space = ["10.0.0.0/16"] |
|
location = azurerm_resource_group.main.location |
|
resource_group_name = azurerm_resource_group.main.name |
|
} |
|
|
|
# Subnet |
|
resource "azurerm_subnet" "aks" { |
|
name = "${var.cluster_name}-subnet" |
|
resource_group_name = azurerm_resource_group.main.name |
|
virtual_network_name = azurerm_virtual_network.main.name |
|
address_prefixes = ["10.0.1.0/24"] |
|
} |
|
|
|
# AKS Cluster |
|
resource "azurerm_kubernetes_cluster" "aks" { |
|
name = var.cluster_name |
|
location = azurerm_resource_group.main.location |
|
resource_group_name = azurerm_resource_group.main.name |
|
dns_prefix = var.dns_prefix |
|
|
|
default_node_pool { |
|
name = "default" |
|
node_count = var.node_count |
|
vm_size = var.vm_size |
|
vnet_subnet_id = azurerm_subnet.aks.id |
|
} |
|
|
|
identity { |
|
type = "SystemAssigned" |
|
} |
|
|
|
network_profile { |
|
network_plugin = "azure" |
|
network_policy = var.enable_network_policy ? "azure" : null |
|
service_cidr = "10.2.0.0/16" |
|
dns_service_ip = "10.2.0.10" |
|
} |
|
|
|
# Azure AD Integration |
|
azure_active_directory_role_based_access_control { |
|
tenant_id = var.tenant_id |
|
azure_rbac_enabled = var.enable_azure_ad_integration |
|
} |
|
|
|
# Monitoring |
|
oms_agent { |
|
log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id |
|
} |
|
|
|
tags = { |
|
Environment = var.environment |
|
} |
|
|
|
lifecycle { |
|
ignore_changes = [azure_active_directory_role_based_access_control] |
|
} |
|
} |
|
|
|
# Traefik Namespace |
|
resource "kubernetes_namespace" "traefik" { |
|
metadata { |
|
name = var.traefik_namespace |
|
} |
|
} |
|
|
|
# Traefik Helm Release |
|
resource "helm_release" "traefik" { |
|
name = "traefik" |
|
repository = "https://helm.traefik.io/traefik" |
|
chart = "traefik" |
|
version = var.traefik_version |
|
namespace = kubernetes_namespace.traefik.metadata[0].name |
|
|
|
set { |
|
name = "deployment.replicas" |
|
value = "2" |
|
} |
|
|
|
set { |
|
name = "globalArguments[0]" |
|
value = "--global.checknewversion=false" |
|
} |
|
|
|
set { |
|
name = "globalArguments[1]" |
|
value = "--global.sendanonymoususage=false" |
|
} |
|
|
|
set { |
|
name = "providers.kubernetesIngress.publishedService.enabled" |
|
value = "true" |
|
} |
|
|
|
set { |
|
name = "ports.web.redirectTo" |
|
value = "websecure" |
|
} |
|
|
|
set { |
|
name = "ports.websecure.tls.enabled" |
|
value = "true" |
|
} |
|
|
|
set { |
|
name = "service.type" |
|
value = "LoadBalancer" |
|
} |
|
|
|
set { |
|
name = "dashboard.enabled" |
|
value = "true" |
|
} |
|
|
|
set { |
|
name = "dashboard.ingress.enabled" |
|
value = "true" |
|
} |
|
|
|
set { |
|
name = "dashboard.ingress.annotations.kubernetes\\.io/ingress\\.class" |
|
value = "traefik" |
|
} |
|
|
|
set { |
|
name = "dashboard.ingress.entrypoints" |
|
value = "websecure" |
|
} |
|
|
|
set { |
|
name = "dashboard.ingress.routes[0].match" |
|
value = "Host(`traefik.${var.dns_prefix}.${var.location}.cloudapp.azure.com`)" |
|
} |
|
} |
|
|
|
# Argo CD Namespace |
|
resource "kubernetes_namespace" "argocd" { |
|
metadata { |
|
name = var.argocd_namespace |
|
} |
|
} |
|
|
|
# Argo CD Helm Release |
|
resource "helm_release" "argocd" { |
|
name = "argocd" |
|
repository = "https://argoproj.github.io/argo-helm" |
|
chart = "argo-cd" |
|
version = var.argocd_version |
|
namespace = kubernetes_namespace.argocd.metadata[0].name |
|
|
|
# Configure Argo CD to run inside the cluster |
|
set { |
|
name = "server.extraArgs[0]" |
|
value = "--insecure" |
|
} |
|
|
|
# Configure the server to be accessible within the cluster |
|
set { |
|
name = "server.service.type" |
|
value = "ClusterIP" |
|
} |
|
|
|
# Enable ingress for external access |
|
set { |
|
name = "server.ingress.enabled" |
|
value = "true" |
|
} |
|
|
|
set { |
|
name = "server.ingress.hosts[0]" |
|
value = "argocd.${var.dns_prefix}.${var.location}.cloudapp.azure.com" |
|
} |
|
|
|
set { |
|
name = "server.ingress.ingressClassName" |
|
value = "traefik" |
|
} |
|
|
|
set { |
|
name = "server.ingress.annotations.kubernetes\\.io/ingress\\.class" |
|
value = "traefik" |
|
} |
|
|
|
set { |
|
name = "server.ingress.annotations.traefik\\.ingress\\.kubernetes\\.io/router\\.entrypoints" |
|
value = "websecure" |
|
} |
|
|
|
set { |
|
name = "server.ingress.annotations.traefik\\.ingress\\.kubernetes\\.io/router\\.tls" |
|
value = "true" |
|
} |
|
|
|
# Configure Redis for Argo CD (runs inside the cluster) |
|
set { |
|
name = "redis.enabled" |
|
value = "true" |
|
} |
|
|
|
# Configure the application controller |
|
set { |
|
name = "controller.replicas" |
|
value = "2" |
|
} |
|
|
|
# Configure the repo server |
|
set { |
|
name = "repoServer.replicas" |
|
value = "2" |
|
} |
|
|
|
# Set admin password |
|
set { |
|
name = "configs.secret.argocdServerAdminPassword" |
|
value = "$2a$10$rRyBsGSHK6.uc8fntPwVIuLVHgsAhAX7TcdrqW/RADU0uh7CaChLa" # "admin" password |
|
} |
|
|
|
# Configure RBAC |
|
set { |
|
name = "server.rbacConfig.policy.default" |
|
value = "role:readonly" |
|
} |
|
|
|
set { |
|
name = "server.rbacConfig.policy.csv" |
|
value = <<-EOT |
|
p, role:org-admin, applications, *, */*, allow |
|
p, role:org-admin, clusters, get, *, allow |
|
p, role:org-admin, repositories, get, *, allow |
|
p, role:org-admin, repositories, create, *, allow |
|
p, role:org-admin, repositories, update, *, allow |
|
p, role:org-admin, repositories, delete, *, allow |
|
g, org-admin, role:org-admin |
|
EOT |
|
} |
|
|
|
lifecycle { |
|
prevent_destroy = false |
|
} |
|
} |
|
|
|
# Backup Policy for AKS |
|
resource "azurerm_backup_policy_vm" "aks" { |
|
name = "aks-backup-policy" |
|
resource_group_name = azurerm_resource_group.main.name |
|
recovery_vault_name = azurerm_recovery_services_vault.main.name |
|
|
|
backup { |
|
frequency = "Daily" |
|
time = "23:00" |
|
} |
|
|
|
retention_daily { |
|
count = 7 |
|
} |
|
|
|
retention_weekly { |
|
count = 4 |
|
weekdays = ["Sunday"] |
|
} |
|
|
|
retention_monthly { |
|
count = 12 |
|
weekdays = ["Sunday"] |
|
weeks = ["First"] |
|
} |
|
} |