diff --git a/README.md b/README.md
index a4c0502..df326b5 100644
--- a/README.md
+++ b/README.md
@@ -18,14 +18,16 @@ The values stored in [/apimartifacts](./apimartifacts/) correspond to the dev en
## Infrastructure overview
-For the MVE we'll use 2 environments. Each environment has its own instance of API management in dedicated VNet.
+For the MVE we'll use 2 types of environment. Each environment has its own instance of API management in dedicated VNet.
+We will have multiple application environment.
For backend applications we'll use shared AKS cluster. Each environment will have its own Kubernetes namespace. All backend services will be exposed via the same
ingress and will be available for APIm by urls:
- apim-mve-dev.${some-public-dns-zone}
+- apim-mve-stage.${some-public-dns-zone}
- apim-mve-prod.${some-public-dns-zone}
-
+
## Pre-Requisites
diff --git a/assets/Azure-Infrastructure.drawio b/assets/Azure-Infrastructure.drawio
new file mode 100644
index 0000000..29273c1
--- /dev/null
+++ b/assets/Azure-Infrastructure.drawio
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/Azure-Infrastructure.png b/assets/Azure-Infrastructure.png
new file mode 100644
index 0000000..b8a6d52
Binary files /dev/null and b/assets/Azure-Infrastructure.png differ
diff --git a/assets/Infra-backend.drawio b/assets/Infra-backend.drawio
deleted file mode 100644
index 771e52e..0000000
--- a/assets/Infra-backend.drawio
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/Infra-backend.drawio.png b/assets/Infra-backend.drawio.png
deleted file mode 100644
index 4b7d1cd..0000000
Binary files a/assets/Infra-backend.drawio.png and /dev/null differ
diff --git a/infrastructure/backend.tf b/infrastructure/backend.tf
new file mode 100644
index 0000000..f11dce3
--- /dev/null
+++ b/infrastructure/backend.tf
@@ -0,0 +1,82 @@
+resource "azurerm_resource_group" "backend_rg" {
+ name = var.backend_rg_name
+ location = var.location
+}
+
+module "aks" {
+ source = "./modules/azure-public-aks"
+ aks_name = var.aks_name
+ aks_rg = azurerm_resource_group.backend_rg.name
+}
+
+resource "azurerm_role_assignment" "aks_pull_acr" {
+ depends_on = [module.aks]
+ scope = azurerm_container_registry.acr.id
+ role_definition_name = "AcrPull"
+ principal_id = module.aks.principal_id
+}
+
+provider "kubernetes" {
+ host = module.aks.host
+ client_certificate = module.aks.client_certificate
+ client_key = module.aks.client_key
+ cluster_ca_certificate = module.aks.cluster_ca_certificate
+}
+
+provider "kubectl" {
+ host = module.aks.host
+ client_certificate = module.aks.client_certificate
+ client_key = module.aks.client_key
+ cluster_ca_certificate = module.aks.cluster_ca_certificate
+ load_config_file = false
+}
+
+provider "helm" {
+ kubernetes {
+ host = module.aks.host
+ client_certificate = module.aks.client_certificate
+ client_key = module.aks.client_key
+ cluster_ca_certificate = module.aks.cluster_ca_certificate
+ }
+}
+
+resource "azurerm_public_ip" "ingress_nginx_public_ip" {
+ name = "${var.aks_name}-ingress-nginx"
+ resource_group_name = module.aks.node_resource_group
+ location = var.location
+ allocation_method = "Static"
+ sku = "Standard"
+ zones = ["1", "2", "3"]
+ ip_tags = {}
+ tags = {
+ k8s-azure-cluster-name = var.aks_name
+ k8s-azure-service = "ingress-nginx/ingress-nginx-controller"
+ }
+}
+
+module "ingress-nginx" {
+ depends_on = [module.aks, azurerm_public_ip.ingress_nginx_public_ip]
+ source = "./modules/kubernetes-ingress-nginx"
+ public_ip_address = azurerm_public_ip.ingress_nginx_public_ip.ip_address
+ providers = {
+ helm = helm
+ }
+}
+
+module "cert-manager" {
+ source = "./modules/kubernetes-cert-manager"
+ acme_email = "aaheiev@gmail.com"
+ providers = {
+ helm = helm
+ kubectl = kubectl
+ }
+}
+
+resource "azurerm_dns_a_record" "backend_a_records" {
+ for_each = toset(var.backend_endpoints)
+ name = each.value
+ zone_name = azurerm_dns_zone.public_dns_zone.name
+ resource_group_name = azurerm_resource_group.services_rg.name
+ ttl = 300
+ records = [azurerm_public_ip.ingress_nginx_public_ip.ip_address]
+}
diff --git a/infrastructure/datasources.tf b/infrastructure/datasources.tf
new file mode 100644
index 0000000..d083adb
--- /dev/null
+++ b/infrastructure/datasources.tf
@@ -0,0 +1,9 @@
+data "azuread_client_config" "current" {}
+
+data "azurerm_role_definition" "aks_cluster_admin" {
+ role_definition_id = "0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8"
+}
+
+data "azurerm_role_definition" "aks_cluster_user" {
+ role_definition_id = "4abbcc35-e782-43d8-92c5-2d3f1bd2253f"
+}
diff --git a/infrastructure/main.tf b/infrastructure/main.tf
index cbe6e79..daeb83b 100644
--- a/infrastructure/main.tf
+++ b/infrastructure/main.tf
@@ -1,56 +1,41 @@
-terraform {
- required_providers {
- azurerm = {
- source = "hashicorp/azurerm"
- version = "~> 3.67.0"
- }
- azuread= {
- source = "hashicorp/azuread"
- version = "~> 2.41.0"
- }
- }
-
- required_version = ">= 0.15.3"
-}
-
-provider "azurerm" {
- skip_provider_registration = "true"
- features {}
-}
-
-provider "azuread" {
-}
-
-# Configure a Service Principal so that we can access the APIM in the different Resource Groups
-data "azurerm_client_config" "current" {}
-
-# The current logged in user will be the owner of the application
-resource "azuread_application" "apim_app" {
- display_name = "api_ops_app"
- owners = [data.azurerm_client_config.current.object_id]
-}
-
-resource "azuread_service_principal" "apim_spn" {
- application_id = azuread_application.apim_app.application_id
- owners = [data.azurerm_client_config.current.object_id]
-}
-
-resource "azuread_service_principal_password" "spn" {
- service_principal_id = azuread_service_principal.apim_spn.id
-}
-
-module "apim_dev" {
- source = "./apim"
- location = var.location
- prefix = var.prefix
- service_principal_object_id = azuread_service_principal.apim_spn.object_id
- environment = "dev"
-}
-
-module "apim_prod" {
- source = "./apim"
- location = var.location
- prefix = var.prefix
- service_principal_object_id = azuread_service_principal.apim_spn.object_id
- environment = "prod"
-}
+## The current logged in user will be the owner of the application
+
+# TODO:
+
+# Deploy helm - AKS admin
+
+# push APIm config to dev
+# push APIm config to dev
+
+# push APIm config to dev
+
+
+# resource "azuread_application" "apim_app" {
+# display_name = "api_ops_app"
+# owners = [data.azurerm_client_config.current.object_id]
+# }
+
+# resource "azuread_service_principal" "apim_spn" {
+# application_id = azuread_application.apim_app.application_id
+# owners = [data.azurerm_client_config.current.object_id]
+# }
+
+# resource "azuread_service_principal_password" "spn" {
+# service_principal_id = azuread_service_principal.apim_spn.id
+# }
+
+#module "apim_dev" {
+# source = "./modules/apim"
+# location = var.location
+# prefix = var.prefix
+# service_principal_object_id = azuread_service_principal.apim_spn.object_id
+# environment = "dev"
+#}
+#
+#module "apim_prod" {
+# source = "./modules/apim"
+# location = var.location
+# prefix = var.prefix
+# service_principal_object_id = azuread_service_principal.apim_spn.object_id
+# environment = "prod"
+#}
diff --git a/infrastructure/apim/apim.tf b/infrastructure/modules/apim/apim.tf
similarity index 100%
rename from infrastructure/apim/apim.tf
rename to infrastructure/modules/apim/apim.tf
diff --git a/infrastructure/apim/outputs.tf b/infrastructure/modules/apim/outputs.tf
similarity index 100%
rename from infrastructure/apim/outputs.tf
rename to infrastructure/modules/apim/outputs.tf
diff --git a/infrastructure/apim/variables.tf b/infrastructure/modules/apim/variables.tf
similarity index 100%
rename from infrastructure/apim/variables.tf
rename to infrastructure/modules/apim/variables.tf
diff --git a/infrastructure/modules/azure-public-aks/datasources.tf b/infrastructure/modules/azure-public-aks/datasources.tf
new file mode 100644
index 0000000..70a3014
--- /dev/null
+++ b/infrastructure/modules/azure-public-aks/datasources.tf
@@ -0,0 +1,5 @@
+data "azuread_client_config" "current" {}
+
+data "azurerm_role_definition" "aks_cluster_user" {
+ role_definition_id = "4abbcc35-e782-43d8-92c5-2d3f1bd2253f"
+}
diff --git a/infrastructure/modules/azure-public-aks/main.tf b/infrastructure/modules/azure-public-aks/main.tf
new file mode 100644
index 0000000..5fa8dd6
--- /dev/null
+++ b/infrastructure/modules/azure-public-aks/main.tf
@@ -0,0 +1,55 @@
+resource "azurerm_kubernetes_cluster" "aks" {
+ name = var.aks_name
+ location = var.aks_location
+ resource_group_name = var.aks_rg
+ dns_prefix = "${var.aks_name}-dns"
+ kubernetes_version = var.aks_version
+ automatic_channel_upgrade = "patch"
+ identity {
+ type = "SystemAssigned"
+ }
+
+ default_node_pool {
+ name = "default"
+ vm_size = var.default_vm_size
+ enable_auto_scaling = true
+ min_count = var.default_pool_min_nodes
+ max_count = var.default_pool_max_nodes
+ os_disk_size_gb = var.default_pool_os_disk_size_gb
+ os_sku = "Ubuntu"
+ tags = {}
+ }
+ network_profile {
+ dns_service_ip = var.dns_service_ip
+ ip_versions = ["IPv4"]
+ load_balancer_sku = "standard"
+ network_plugin = "kubenet"
+ outbound_type = "loadBalancer"
+ pod_cidr = var.aks_pod_cidr
+ service_cidr = var.aks_service_cidr
+ }
+}
+
+resource "azuread_application" "aks_cluster_user" {
+ display_name = format("%s%s", var.aks_name, "-user")
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "aks_cluster_user" {
+ application_id = azuread_application.aks_cluster_user.application_id
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azurerm_role_assignment" "aks_cluster_user" {
+ scope = azurerm_kubernetes_cluster.aks.id
+ role_definition_id = data.azurerm_role_definition.aks_cluster_user.id
+ principal_id = azuread_service_principal.aks_cluster_user.object_id
+
+ lifecycle {
+ ignore_changes = [role_definition_id] # see https://github.com/hashicorp/terraform-provider-azurerm/issues/4258
+ }
+}
+
+resource "azuread_service_principal_password" "aks_cluster_user_password" {
+ service_principal_id = azuread_service_principal.aks_cluster_user.object_id
+}
diff --git a/infrastructure/modules/azure-public-aks/outputs.tf b/infrastructure/modules/azure-public-aks/outputs.tf
new file mode 100644
index 0000000..cdd877a
--- /dev/null
+++ b/infrastructure/modules/azure-public-aks/outputs.tf
@@ -0,0 +1,23 @@
+output "principal_id" {
+ value = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
+}
+
+output "host" {
+ value = azurerm_kubernetes_cluster.aks.kube_config.0.host
+}
+
+output "client_certificate" {
+ value = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
+}
+
+output "client_key" {
+ value = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
+}
+
+output "cluster_ca_certificate" {
+ value = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
+}
+
+output "node_resource_group" {
+ value = lower(azurerm_kubernetes_cluster.aks.node_resource_group)
+}
diff --git a/infrastructure/modules/azure-public-aks/variables.tf b/infrastructure/modules/azure-public-aks/variables.tf
new file mode 100644
index 0000000..9032124
--- /dev/null
+++ b/infrastructure/modules/azure-public-aks/variables.tf
@@ -0,0 +1,52 @@
+variable "aks_name" {
+ type = string
+}
+
+variable "aks_rg" {
+ type = string
+}
+
+variable "aks_location" {
+ type = string
+ default = "West Europe"
+}
+
+variable "aks_version" {
+ type = string
+ default = "1.26.6"
+}
+
+variable "aks_pod_cidr" {
+ type = string
+ default = "10.244.0.0/16"
+}
+
+variable "aks_service_cidr" {
+ type = string
+ default = "10.0.0.0/16"
+}
+
+variable "dns_service_ip" {
+ type = string
+ default = "10.0.0.10"
+}
+
+variable "default_vm_size" {
+ type = string
+ default = "Standard_B2als_v2"
+}
+
+variable "default_pool_min_nodes" {
+ type = number
+ default = 2
+}
+
+variable "default_pool_max_nodes" {
+ type = number
+ default = 5
+}
+
+variable "default_pool_os_disk_size_gb" {
+ type = number
+ default = 32
+}
diff --git a/infrastructure/modules/kubernetes-cert-manager/helm-chart-values.template.yaml b/infrastructure/modules/kubernetes-cert-manager/helm-chart-values.template.yaml
new file mode 100644
index 0000000..e7361d2
--- /dev/null
+++ b/infrastructure/modules/kubernetes-cert-manager/helm-chart-values.template.yaml
@@ -0,0 +1,5 @@
+---
+installCRDs: true
+ingressShim:
+ defaultIssuerName: letsencrypt
+ defaultIssuerKind: ClusterIssuer
diff --git a/infrastructure/modules/kubernetes-cert-manager/issuer.letsencrypt.template.yaml b/infrastructure/modules/kubernetes-cert-manager/issuer.letsencrypt.template.yaml
new file mode 100644
index 0000000..f71e6b7
--- /dev/null
+++ b/infrastructure/modules/kubernetes-cert-manager/issuer.letsencrypt.template.yaml
@@ -0,0 +1,19 @@
+---
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+metadata:
+ name: letsencrypt
+spec:
+ acme:
+ email: ${acme_email}
+ server: ${acme_url}
+ privateKeySecretRef:
+ name: letsencrypt
+ solvers:
+ - http01:
+ ingress:
+ class: nginx
+ ingressTemplate:
+ metadata:
+ annotations:
+ ingress.kubernetes.io/whitelist-source-range: "0.0.0.0/0,::/0"
diff --git a/infrastructure/modules/kubernetes-cert-manager/main.tf b/infrastructure/modules/kubernetes-cert-manager/main.tf
new file mode 100644
index 0000000..ce752f7
--- /dev/null
+++ b/infrastructure/modules/kubernetes-cert-manager/main.tf
@@ -0,0 +1,50 @@
+locals {
+ acme_url = "https://acme-v02.api.letsencrypt.org/directory"
+ chart_repo = "https://charts.jetstack.io"
+ chart_name = "cert-manager"
+ k8s_namespace = "cert-manager"
+}
+
+resource "kubernetes_namespace" "namespace" {
+ metadata {
+ name = local.k8s_namespace
+ }
+ lifecycle {
+ ignore_changes = [metadata[0].labels]
+ }
+}
+
+resource "kubernetes_secret" "letsencrypt" {
+ count = var.letsencrypt_tls_key == "" ? 0 : 1
+ metadata {
+ name = "letsencrypt"
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ }
+ data = {
+ "tls.key" = var.letsencrypt_tls_key
+ }
+ # ignore change so secret is not updated on every run
+ lifecycle {
+ ignore_changes = [
+ data
+ ]
+ }
+}
+
+resource "helm_release" "cert-manager" {
+ name = "cert-manager"
+ repository = local.chart_repo
+ chart = local.chart_name
+ version = var.chart_version
+ namespace = local.k8s_namespace
+ force_update = true
+ create_namespace = false
+ wait = true
+ timeout = 300
+ values = [file("${path.module}/helm-chart-values.template.yaml")]
+}
+
+resource "kubectl_manifest" "issuer" {
+ depends_on = [helm_release.cert-manager]
+ yaml_body = templatefile("${path.module}/issuer.letsencrypt.template.yaml", { acme_email = var.acme_email, acme_url = local.acme_url } )
+}
diff --git a/infrastructure/modules/kubernetes-cert-manager/terraform.tf b/infrastructure/modules/kubernetes-cert-manager/terraform.tf
new file mode 100644
index 0000000..03ae157
--- /dev/null
+++ b/infrastructure/modules/kubernetes-cert-manager/terraform.tf
@@ -0,0 +1,11 @@
+terraform {
+ required_providers {
+ kubectl = {
+ source = "gavinbunney/kubectl"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ }
+ }
+}
+
diff --git a/infrastructure/modules/kubernetes-cert-manager/variables.tf b/infrastructure/modules/kubernetes-cert-manager/variables.tf
new file mode 100644
index 0000000..9b44780
--- /dev/null
+++ b/infrastructure/modules/kubernetes-cert-manager/variables.tf
@@ -0,0 +1,15 @@
+variable "acme_email" {
+ type = string
+ description = "ACME registration email"
+}
+
+variable "chart_version" {
+ type = string
+ default = "v1.12.3"
+}
+
+variable "letsencrypt_tls_key" {
+ type = string
+ default = ""
+ description = "Letsencrypt tls key"
+}
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.1.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.1.pem
new file mode 100644
index 0000000..bf35f56
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.1.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEAzUu4XzM3eLADlZTUP4kVr+wqXnNCd8kuFKJhC2rzdh/QZoqGbDuU
+zXeZMwHe4z1Js2k/WHKjK2nren16f+qB1Y0TCgzAaCrNFiejdb2H/HV81nxMXysv
+BdT+mYZ/u27wKZESHyLVMuhnJtErAs08LS0xr+9pdbRNRJOUwuNTqDF8AE7SNtK4
+VmJWnV2JV5Orx0nv9mJw4rVklpdvBeS8el8oxUSlpa82m6ugxuCL9GCQDjQuk9Yg
+VZCyJ2F36kts6Ziv86DBfx0Im/Q0a+KPDlpr/SZLiNhVYfXAC0beHL0ejc+t45RG
+zAQI6DnEUxxQjIUVouEweDjJrTOw7GEE8dTextE+gKW1uAmar8Q0Fs8Jg0Lu9IH8
+i7wdqbNc7dEMVSHP2KZ/we1UZskyuKaICVgyJJ3vlvST0U2NTAaMCpA62Fv98Qlx
+9SBME/4UGcGmSsYcoudDpzQaUej1mUi0NKhy6vulXJGUhSLIhtmWwp4t/EKN/h9E
+RTSk6JDByv6MeJBZJvNsCuJMFhN/V+g03pgURreTPhn59PykgAItMHiOlbpbqUYj
+2c6f+9zHFA0Bq7YthKVqoDTBgDWI2uVzlnFPwFACl4RkxEZmTXtceq+ijHKDOkoK
+L6pIMLt8udthc9SjrhygbvveVX/F53SMhJZrzDN5V8GtqmxKxg1C508CAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.10.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.10.pem
new file mode 100644
index 0000000..7a14a73
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.10.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEAzVBjSBNllypi7XzLOh+wtSD1Hco07Nwux6di2Y6TqqbNdp4F40Gj
+WHn26rSqRQMWbBG3T5HJTL5ha39E4NCxaqj4Z9rqeXEsw9XXyfdwZ9BKTP9qepaF
+6JCTKyhstFGJti/o9EfYr2s0FJskq1hGClE42kAXNJEmOsi5iasPtZyjjbKaV5Qo
+CR0BzsjJBT4TIHsoX7h61g3bQ5MxMkAOF8ELgxTFZICt3Q2JtjUV/CrTLYr7IpF6
+3yKyTg8osnU/qagIVgwcpOUGHQZawSFT03NCaTFYpZ4zkFgZiB7Q1JrejkevIWtt
+ol7VIhpfTeWIjxtytUiz0Ve4PMh54DLLdUYuBHCjjPBnEKR2VL6C8dA9WakK6No2
+nnfZzqLXqA2k10CkWhBpqSGApJa649lDZs/Aotf05as476FTQ+Q3MwkMPT8BhyaB
+bmG6iPVrDDHtHPWMVYvHbakbgodwGZlgZ8ClRI1aFS4RzHwpMabsAcrHDhMyG/TU
+MTQ6uAO9S6/7bh06cO46RyAVYuLgjDYJQYh0LIacTR/4UvhR/wKR+9Ik7DRDChxT
+pBCe6g9QgjkqQ2VQuY/BAGqrk5DMIUfKu7JEXknEQiUvY1s61y70yqynqTsnmTiW
+bnQQxSqcpUFrVbAMXIJMXXjNczf2paColjyWDCxXR81mBE2aFcsZxucCAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.2.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.2.pem
new file mode 100644
index 0000000..409c15a
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.2.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA0Mt9VV1iQEd9LcL+A4XqXD/u0AIufl39s5jPug22/CTO23IKzzfk
+dFIwmdldWN2EBKdXCMlNF/UNweUa+3xWQBbi9m9/tyIfMFg8B5VZCcliAcuy5GhN
+cIWDu6JzW41p6uhPwWfWrTPdIXNehyVAtRFa7t3ukMVEzECM9Drzg1N9cld7UxrC
+GSK7vOJ1CaKSHN4vE3XMFkAqszLDtAJI321maHeOAKG4Z9k0ywtlS1AeOZ+p4OUE
+lWYJ/R37R1D8b3r/GgOCK/48O30ZxwrVxBrlR57ghtitalW3SBlnb4rle7r1CgTD
+Nfwfj9NkhgHxvyH8/KiJr99zvYagZgRXm0nK9yYGJu+RaMHoeq7XCJ6UpEm4n+fd
+T7yBBoiM+lpeo7EWX1d7yi0UwkeoYX5LW/x0/V5zrGR8pBbQOisApNf3rJSO0v+j
+zaT6xOFQJYDwpFQZ8lwggv6s6LeNz2b+sfoxUBUv/6133Ub6m6deqJVEyeHH1CWG
+JLp+Tec4yR89zNT1V6Czd+sh6or0+T/N0AIqtrWJA2scuc9iqpaDTjXbBXXUkWnJ
+G9wJ8zhH9uE+YCFYYIAOyYi/iRIJS20Dpa6TWqNNmFu/1iJdM3s6obLJM64byiPB
+zD6Moyd0AD/7jkAmtVqVrWmE1HzTU/VobkrkzfnB35d3bQtO+z74C9MCAQI=
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.3.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.3.pem
new file mode 100644
index 0000000..d394ada
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.3.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEArTWADhv8gSHvG8aKcEmjuqpi9jBpHEklk9OXd8+4vXhuL85oEbsR
+esNYA2BcgTgLfieZkx1TkJvkg84i92fcDqANEFeTvfeDqF9/nDhlUu9xTht8KsO0
+y4Zry3HMZwttoWxni9rHr11C0pZAaHJd0Y+r/n0gTTrndtakWfNIzttLotcEjkQp
+0FHCGCTgzS4iN1dqAC0OAbZ9v4aks4iBSrzazbqAr06bXKZZYL17aW6RlgohBje5
+zupC6WDQ9pvqqXZUm/lYJB0WU8bdCSBfNG6Rq9xcopOr44DT9Dt/nY8fpm869KFz
+5LxrCMfUrJ2rxsSBk6b1ecshtZp6ep3/A6+TJ6vMy377Xup+LJV+JF8zBkWs4Lmq
+144T6H/ORKyBxxhAsR7ubQZeQjB5j9+m4GP7LPFPelRYkwnc33IFEcsJWQ617WH9
+Pp47g1or34ji4HWb1g/97NEXgKA0pSUMHqLJ5KdWtWIul/qatrg31t6uj3yu2/j6
+7htYbw40zqeiBCaSoxuWRlSF8GI3mAWSagkO1GrGx9lycWVv0IkUNZ1MULtS6fNG
+b+DLrLroCk2hbfApDbKBWFzW4LIjzUGh7FVANTb5sULdvAO8r0SGm2XDouY1d12T
+TFATUGPLSFgk9rkYFiAU9UmZiJFRof5obPGOrOYhRkPvHnFnkaKdN0sCAQI=
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.4.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.4.pem
new file mode 100644
index 0000000..8fffaf5
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.4.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA/6IqMpqMqEwOajM18EAhjv4/I55SOJh/jEIxESlzr8qmNfjElMfp
+jm9KFS+VPdkl1zoEPLNQjwIIq+2ILfD1vIPV6IFz/YEgj2nNlYIg7k1V5oJEY8h9
+iA1xEopotyeB5Jh3o16A4mwwBe8sGPh9yvvalSGsN3QfbM7SVk+I5uSR7ZjlZ0Gn
+g4zWMWoOONBYTySaLRYvKmHmnzvsy4Z9Q2rTPpF/SdRA2NV/q8Aon9hUU+HWCDgj
+kGWm4qYQezO3GeFvGzIm9i9G6dXroKhnp6bRPdWPa2sdj+aWqTwjYXFIDfSwYYw2
+688lAuk5VSgkg7i5qCH5eaVrmzK34jHW28j8xUHb1a5z3KD3XUBEsQEfJK7iwaSc
+srh3b9IiSxEaGxendN7tccoGcr7yDgyuA958lLZ1nyUOTa+rHM57Hs7Z17q6D2Ju
+fsJlRvGaLjE5VN/AoRgXsgZD+llvSmQYS+TYuEd3KU5g5OaiWAJc/h5p1gut8ipk
+fDRWh75D9Hi0BWpgCDArMQXcKkygC4lTCk+DssRWpeSlV7OUXFNJju/R9C98Py8L
+3ymuzZknxY5dkNeZ6OxRS7rJrMOY4bMaJB8zMCE2f/KjFrl3/62v689ifEHikgSt
+EYc6ywYzFuJ0jeAEgYxBVzP3vwngQb1h/oMGnRJbl19EYoz7Ez4EBQsCAQI=
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.5.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.5.pem
new file mode 100644
index 0000000..5e2422c
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.5.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEAjyc5ONxY0/gc4n3QZ+opJjvwyNaj4be6/MOVZvshnL/W26GB71B5
+slGzeNp8U4PaEBH3T0hJWaNFnXXIb2B6CfTJN5knE9SNeK+5YbLi74I6wnAiu2D0
+qL78y8dGTqTEUfbhd/G22SSZ0CUbhkY3YzkFrCRTAWYp18bWhHja4DEyyUCcMmMX
+OuA6VlhuIiJeLaz6BnQtc0U7WwnbaJazSXH8YuEuXzG8ChK5Fj+E42EVpai+l7sS
+JbmtzAgpfRJ16MvWdPzN+ZrKTI805Ydd/u+9U5FjQ+eOyx17oKpMO6tGgMkxRI/4
+nDILCBQeM1GLl8pGxfFnn1XHV2adM1Mt8I5b1N7IeG6NH/gc5KRw521x2691uN7q
+l4yEV1NEEPWzyrXxqsF2IL05aBQ5zRG6cctzqCAr7BvXYdO5hDmqjTxrBfLAFBxZ
+vpWsulre1/wWohHACW/xSzwVIQ7vvei+HHgrylPqpG7A6cd88ehExOlLceqra4EM
+aQ3LE8IwVy+gEQB5TMqDRMvNPZuJ/EgXV3rEOaTAS+GHV6+ZgPJMZyPOuoFQDz13
+geXJHPBnFXd3BVHISZd1R8ZsakODUc2MFKAvyrM2ZAbKdUKBRIkh+l7QL6LioAAH
+l9tATmhBN0jSrod6UFbJ1jbKvdfuSOaI4JOtMoEapGAZ9iqMvrCTNt8CAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.6.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.6.pem
new file mode 100644
index 0000000..a0e9661
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.6.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEA+Wm2PX0U3b6WgglpkqISDSHACDPdg+OqFUmLACv+uLdI+ke5mEYG
+Tiw3nqh07RlnGcLwQQZSiKm8z1G+m+FrC3ZqM+2Dl20Ieb7zy8+9KeeSHaZibJt8
+O0oHAhkQq6Y7q4bzhVkgxKu+mOV3dEb1RvqD9ENKcENQDdhhmLo6tFhOcySdvE8O
+JMbKfNSXRlRTyrJ1Xm5dF02/PhiS40DefW+DHS7PLPhDIKn9eG1eiks2iwCQbNsU
+4RYxB0BIzIKki+Mak+zQEHAHGetfekbzD/UQnBg1hKwDOWXrQ6AGDW7xO2I6GoX+
+8QAEqrSN0zAOOPgxRmevJqb01SwCS1aW4KdSO9tR/pyvYqqlqatMjGg26uZaC+Jo
+gBuvEQX8PLunTBznjqvIhsaxCdje1gMTRMIYsNqZIwjAAutrFa3AD0fIkb4PR7zN
+nSXykp3n63VH1FCfqvaHgp1KyGEkwB7oyJzZDe/yJdsOf9xQPIBGUqwmzHMkWK3e
+s0f9lncfotTOZdxY2xGwmSaRUpVldbm4CVMGwbymU8xxmLoKbKP7KZukXCvWXkji
+3OhyBXsOJdR2sT2RC3WluUcnHtLSg+9mtSmYszzqknBcaLZKdiGA+Dsg+kiGUSA8
+zsboRLeB42gxrufOnkZUiCc8Ol2UN/pktAircdXQKHS776rSMSeHge8CAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.7.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.7.pem
new file mode 100644
index 0000000..816182d
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.7.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEAzENSLXAzGvg0Ek59caTJd6+OKVSN9edO/omYazlSWdesXDjC8R3Z
+k4wdAMKjKELQfle/J7AQxXHwgWHU5ZqCSYLia1Zwpy5kku24RXGa3z3FmHeXj96M
+j1WqpTBGmDiCPrZK1+FOpfqVGaq/Gsr5/iiIX4Mo3DYFhp6KPiswL6FKbKLvNIep
+wf80V0gawzZ/q+grcppHhcd2JeAjSRq/wG39s8IOoFAPNdix3SmsSr3sb7ulVCYa
+e/gL/bTtxtA455hy62/DOULuV5Ukeb0xtp39Q3Cru/YqlTpJBb3Y/7m+EKJi2Dv5
+afh68OGeMKEdA9kp07Zq5sG9gb+0birOjdDOMKWytTX3Rx61Y340kUUGYZfoavgZ
+mrHOvj9SAHHLYZDDzQ1R2OT9bUdu2hWJsIGRCL99kmN3JdYi8J/CowW1+GA7Sw7s
+LLpCRPd8BEe83+Js62DK8fmrSnvV3IisB9MgtC9nrhAglGOlPQJOZH1nZrV57D1l
+LRhEzEExNS/Q79BBoygSET5L3bjkjzh9v6cY+ZO0yprykRaWj+i2L/nq77sdqg/c
+dX7gKjbasrrDllx1swfzoW8BOjripvSK+pqf/90KBoH8p6ALQkQhX8HRetUciPcN
++x2in1N1vJMWQBNPQf2wIpAXN+THpEEDIgkWez5j0vtOhHiCQ/rAXLcCAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.8.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.8.pem
new file mode 100644
index 0000000..6983fba
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.8.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEAlyMr5YtT5EJQxCeZTt+b5TXC3hQ+Ouc5TrWRhSPjx2AApxZsjISr
+5N2QvGUkBCSR7yUaZyzBuZpwM3QpY4GzFVaOzLfBkWO4qEA8TNx2U+7Tcu3akuM1
+ExLr0iDbN4bQ125R/4idMN8M/DL2y56fG7COBaMs+fksPKHULqhLvhrHvTkItf04
+0rmKokp0DyN+yeGT6V9ePl8UdEYm4DSRI95fLrA4ERb7oS8EhmxbDEajwyTC9g7U
+Jn0Atq1QDcwqQefnPaFq7l1yQDj8dAe5iquTFmXVlKOXq4lky3WmaC5dAU1HOjkY
+Q/Wci6sY+4xFW/6ABJjKZA9tjGG6zYRM/SAV0hdOtxTWppgXIsnEpYuHz6+Iq85G
+9mV0exBbZV/YOPeNyoDJ6UZF/RxCWxpG8EBl2PNwowAOqAgNGSa11oTzfQHCr4Lv
+0RP55m8bcPypM0aFIu9FbP0JgUFwDk5P+KJbMJ4zxGQvgIw/mAyl2hlqN/i/VY/e
+sSB0TzZkpuj3xJ2F5Ul7UlSeVdguds2W4i4UNXE09SQxvaEAjd2dwN/rWsy9cJUu
+uYgw+7uVS+ELmi2ffXMlYl30SUq8mHt9L+6fqGS/bMVeMepwLA6Oro34jgTGtxA9
+J09J84Qci13DIa/cELDKPHSJw6urgmcieCpFrT5SXhOUF1vdffVd458CAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.9.pem b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.9.pem
new file mode 100644
index 0000000..f8686eb
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/dhparam/dhparams.4096.9.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICDAKCAgEA+22cdI48o65YrlXO1fUVQ695jwQWEXCjBc3chscVgsQ3/aTHOWvm
+73jihxFQqYCWj4M6zf2TqkLYV/ZI1msp4hXm3RzkwtKju6VuVPNkPhgZkaQsOiYr
+gX5ukl1yMsgXevU67dON9nivbhSlEXxkQktsz5DSP9CO/fcPLUY+or6NtFGiRF5U
+GSWpeusCCt+jAbQLcf15W51bcjfSMd5wVrDTsXO01LcJqxUU1Eg/8a7B9gY66BKu
+cHN143NtN/YN8Yv5Y8Cz+2nueSLhHniUiaEKhkdNzkXLUzbCrvHzFF5VoMP2w2k0
+JNdyoDlSrgCMyLaiehxQV8u0t+MIXPVN8Co6VJAi9PMizVDFm6riQdgx0QaL9zjR
+4UnNgGRuaqVWZihOa2Qp3XSf6PjKWCJvnysloqeLuPJsw/wYY0F1jnENdteqo8g1
+q3eVPf4I4ClvHvEUNMSHTI9bH5s71tkuPluFj1ARTHyOxhRkyYQSjNW6HDIblVSF
+XH7lT9dzn09mTFjlVzfzEx9ndLzhGwDXukn3983b7yWz+CPCGCTp7+d48lXxAzaf
+e57VjStN75Rb+VpxUM3VShQ7PlOXkIMzkgTmcVye0NaWL2htR3C+o5h4sapPbOfX
+SlCmHC43mJWqphIJP1ngRkAKl0j0V5LuSSdTa1oyi7odNpOI2Z/rRR8CAQICAgFF
+-----END DH PARAMETERS-----
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/helm.values.bak.yaml b/infrastructure/modules/kubernetes-ingress-nginx/helm.values.bak.yaml
new file mode 100644
index 0000000..f517b9f
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/helm.values.bak.yaml
@@ -0,0 +1,56 @@
+---
+controller:
+ kind: Deployment
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 1
+ stats:
+ enabled: true
+ metrics:
+ enabled: true
+ service:
+ labels:
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "10254"
+ publishService:
+ enabled: true
+ extraArgs:
+ v: "2"
+ config:
+ max-worker-connections: "16384"
+ worker-processes: "1"
+ map-hash-bucket-size: "128"
+ server-tokens: "false"
+ ssl-protocols: "TLSv1.2 TLSv1.3"
+ ssl-ciphers: "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
+ ssl-session-cache: "true"
+ ssl-session-cache-size: "10m"
+ ssl-session-tickets: "false"
+ ssl-session-timeout: "5m"
+ ssl-buffer-size: "8k"
+ proxy-read-timeout: "3600"
+ proxy-send-timeout: "3600"
+ keep-alive: "65"
+ use-gzip: "true"
+ proxy-body-size: "10m"
+ ssl-ecdh-curve: "prime256v1"
+ upstream-keepalive-connections: "32"
+ enable-brotli: "false"
+ service:
+ externalTrafficPolicy: "Local"
+ resources:
+ limits:
+ cpu: 500m
+ memory: 768Mi
+ requests:
+ cpu: 50m
+ memory: 128Mi
+ admissionWebhooks:
+ enabled: true
+ autoscaling:
+ enabled: true
+ minReplicas: 2
+ maxReplicas: 5
+ targetCPUUtilizationPercentage: 75
+ targetMemoryUtilizationPercentage: 95
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/helm.values.yaml b/infrastructure/modules/kubernetes-ingress-nginx/helm.values.yaml
new file mode 100644
index 0000000..9cde41d
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/helm.values.yaml
@@ -0,0 +1,47 @@
+---
+controller:
+ kind: Deployment
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 1
+ stats:
+ enabled: "true"
+ metrics:
+ enabled: "true"
+ service:
+ labels:
+ prometheus.io/scrape: "true"
+ prometheus.io/port: "10254"
+ publishService:
+ enabled: "true"
+ extraArgs:
+ v: "2"
+ config:
+ max-worker-connections: "16384"
+ worker-processes: "1"
+ map-hash-bucket-size: "128"
+ server-tokens: "false"
+ ssl-protocols: "TLSv1.2 TLSv1.3"
+ ssl-ciphers: "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
+ ssl-session-cache: "true"
+ ssl-session-cache-size: 10m
+ ssl-session-tickets: "false"
+ ssl-session-timeout: 5m
+ ssl-buffer-size: 8k
+ proxy-read-timeout: "3600"
+ proxy-send-timeout: "3600"
+ keep-alive: "65"
+ use-gzip: "true"
+ proxy-body-size: 10m
+ ssl-ecdh-curve: prime256v1
+ upstream-keepalive-connections: "32"
+ enable-brotli: "false"
+ service:
+ externalTrafficPolicy: Local
+ autoscaling:
+ enabled: "true"
+ minReplicas: 1
+ maxReplicas: 5
+ targetCPUUtilizationPercentage: 75
+ targetMemoryUtilizationPercentage: 95
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/main.tf b/infrastructure/modules/kubernetes-ingress-nginx/main.tf
new file mode 100644
index 0000000..030c265
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/main.tf
@@ -0,0 +1,71 @@
+locals {
+ chart_repo = "https://kubernetes.github.io/ingress-nginx"
+ chart_name = "ingress-nginx"
+ release_name = "ingress-nginx"
+ k8s_namespace = "ingress-nginx"
+ dhparam_secret_name = "nginx-dh-param"
+}
+
+resource "kubernetes_namespace" "namespace" {
+ metadata {
+ name = local.k8s_namespace
+ }
+ lifecycle {
+ ignore_changes = [metadata[0].labels]
+ }
+}
+
+resource "random_integer" "dhparam_file_id" {
+ count = var.dhparam_pem == "" ? 1 : 0
+ min = 1
+ max = 5
+}
+
+locals {
+ dhparam = var.dhparam_pem == "" ? file("${path.module}/dhparam/dhparams.4096.${random_integer.dhparam_file_id[0].result}.pem") : var.dhparam_pem
+ chart_values = var.chart_extra_values == "" ? [file("${path.module}/helm.values.yaml")] : [file("${path.module}/helm.values.yaml"), var.chart_extra_values]
+}
+
+resource "kubernetes_secret" "nginx-dh-param" {
+ metadata {
+ name = local.dhparam_secret_name
+ namespace = kubernetes_namespace.namespace.metadata[0].name
+ }
+ data = {
+ "dhparam.pem" = local.dhparam
+ }
+ # ignore change so secret is not updated on every run
+ lifecycle {
+ ignore_changes = [
+ data
+ ]
+ }
+}
+
+resource "helm_release" "ingress-nginx" {
+ depends_on = [kubernetes_namespace.namespace, kubernetes_secret.nginx-dh-param]
+ name = local.release_name
+ repository = local.chart_repo
+ chart = local.chart_name
+ version = var.chart_version
+ namespace = local.k8s_namespace
+ force_update = true
+ wait = true
+ create_namespace = false
+ values = local.chart_values
+ dynamic "set" {
+ for_each = var.chart_values_overrides
+ content {
+ name = set.key
+ value = set.value
+ }
+ }
+ set {
+ name = "controller.service.loadBalancerIP"
+ value = var.public_ip_address
+ }
+ set {
+ name = "controller.config.ssl-dh-param"
+ value = "${local.k8s_namespace}/${local.dhparam_secret_name}"
+ }
+}
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/terraform.tf b/infrastructure/modules/kubernetes-ingress-nginx/terraform.tf
new file mode 100644
index 0000000..4eabed9
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/terraform.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_providers {
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ }
+ kubectl = {
+ source = "gavinbunney/kubectl"
+ }
+ }
+}
diff --git a/infrastructure/modules/kubernetes-ingress-nginx/variables.tf b/infrastructure/modules/kubernetes-ingress-nginx/variables.tf
new file mode 100644
index 0000000..d1bf5f3
--- /dev/null
+++ b/infrastructure/modules/kubernetes-ingress-nginx/variables.tf
@@ -0,0 +1,29 @@
+variable "public_ip_address" {
+ type = string
+ description = "Public IP address"
+ default = ""
+}
+
+variable "chart_version" {
+ type = string
+ description = "ingress-inginx helm chart version"
+ default = "4.7.1"
+}
+
+variable "chart_values_overrides" {
+ type = map(string)
+ description = "variable = value to override in helm release"
+ default = {}
+}
+
+variable "dhparam_pem" {
+ type = string
+ description = "DH Parameters (pem)"
+ default = ""
+}
+
+variable "chart_extra_values" {
+ type = string
+ description = "ingress-nginx helm release extra values (yaml)"
+ default = ""
+}
diff --git a/infrastructure/outputs.tf b/infrastructure/outputs.tf
index 915a108..d638ffd 100644
--- a/infrastructure/outputs.tf
+++ b/infrastructure/outputs.tf
@@ -1,40 +1,40 @@
-output "azure_subscription_id" {
- description = "Azure Subscription ID."
- value = data.azurerm_client_config.current.subscription_id
-}
+# output "azure_subscription_id" {
+# description = "Azure Subscription ID."
+# value = data.azurerm_client_config.current.subscription_id
+# }
-output "azure_tenant_id" {
- description = "Azure Tenant ID."
- value = data.azurerm_client_config.current.tenant_id
-}
+# output "azure_tenant_id" {
+# description = "Azure Tenant ID."
+# value = data.azurerm_client_config.current.tenant_id
+# }
-output "apim_client_id" {
- description = "APIM Client ID."
- value = azuread_application.apim_app.application_id
-}
+# output "apim_client_id" {
+# description = "APIM Client ID."
+# value = azuread_application.apim_app.application_id
+# }
-output "apim_client_secret" {
- description = "APIM Client Secret."
- value = azuread_service_principal_password.spn.value
- sensitive = true
-}
+# output "apim_client_secret" {
+# description = "APIM Client Secret."
+# value = azuread_service_principal_password.spn.value
+# sensitive = true
+# }
-output "dev_apim_name" {
- description = "Development APIM Name."
- value = module.apim_dev.apim.apim_name
-}
+# output "dev_apim_name" {
+# description = "Development APIM Name."
+# value = module.apim_dev.apim.apim_name
+# }
-output "prod_apim_name" {
- description = "Production APIM Name."
- value = module.apim_prod.apim.apim_name
-}
+# output "prod_apim_name" {
+# description = "Production APIM Name."
+# value = module.apim_prod.apim.apim_name
+# }
-output "dev_resource_group_name" {
- description = "Development Resource Group Name."
- value = module.apim_dev.apim.resource_group_name
-}
+# output "dev_resource_group_name" {
+# description = "Development Resource Group Name."
+# value = module.apim_dev.apim.resource_group_name
+# }
-output "prod_resource_group_name" {
- description = "Production Resource Group Name."
- value = module.apim_prod.apim.resource_group_name
-}
+# output "prod_resource_group_name" {
+# description = "Production Resource Group Name."
+# value = module.apim_prod.apim.resource_group_name
+# }
diff --git a/infrastructure/services.tf b/infrastructure/services.tf
new file mode 100644
index 0000000..76c1c83
--- /dev/null
+++ b/infrastructure/services.tf
@@ -0,0 +1,32 @@
+# common services resources
+
+resource "azurerm_resource_group" "services_rg" {
+ name = var.services_rg_name
+ location = var.location
+}
+
+resource "azurerm_dns_zone" "public_dns_zone" {
+ name = var.dns_domain
+ resource_group_name = azurerm_resource_group.services_rg.name
+}
+
+resource "azurerm_container_registry" "acr" {
+ name = var.acr_name
+ resource_group_name = azurerm_resource_group.services_rg.name
+ location = azurerm_resource_group.services_rg.location
+ sku = "Standard"
+ admin_enabled = false
+ anonymous_pull_enabled = false
+ data_endpoint_enabled = false
+ zone_redundancy_enabled = false
+}
+
+resource "azurerm_key_vault" "akv" {
+ name = var.akv_name
+ location = azurerm_resource_group.services_rg.location
+ resource_group_name = azurerm_resource_group.services_rg.name
+ tenant_id = var.tenant_id
+ sku_name = "standard"
+ enable_rbac_authorization = true
+ soft_delete_retention_days = 90
+}
diff --git a/infrastructure/terraform.tf b/infrastructure/terraform.tf
new file mode 100644
index 0000000..35e7ecd
--- /dev/null
+++ b/infrastructure/terraform.tf
@@ -0,0 +1,51 @@
+terraform {
+ required_version = ">=1.5.4"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 3.65.0"
+ }
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "~> 2.40.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "~> 3.5.1"
+ }
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = ">= 2.22.0"
+ }
+ helm = {
+ source = "hashicorp/helm"
+ version = ">= 2.10.1"
+ }
+ kubectl = {
+ source = "gavinbunney/kubectl"
+ version = ">= 1.14.0"
+ }
+ sops = {
+ source = "carlpett/sops"
+ version = ">= 0.7.2"
+ }
+ }
+ backend "azurerm" {
+ resource_group_name = "infra"
+ storage_account_name = "apimmvetfstate"
+ container_name = "tfstate"
+ key = "apim-mve.tfstate"
+ }
+}
+
+provider "azurerm" {
+ subscription_id = var.subscription_id
+ tenant_id = var.tenant_id
+ skip_provider_registration = true
+ features {}
+}
+
+#provider "azuread" {
+#}
+#
+#data "azurerm_client_config" "current" {}
diff --git a/infrastructure/variables.tf b/infrastructure/variables.tf
index ea51203..77da3d0 100644
--- a/infrastructure/variables.tf
+++ b/infrastructure/variables.tf
@@ -1,9 +1,52 @@
+variable "subscription_id" {
+ type = string
+}
+
+variable "tenant_id" {
+ type = string
+}
+
variable "location" {
type = string
description = "Specifies the supported Azure location (region) where the resources will be deployed"
+ default = "West Europe"
}
-variable "prefix" {
- type = string
- description = "Prefix for resource names"
+#variable "prefix" {
+# type = string
+# description = "Prefix for resource names"
+#}
+
+variable "services_rg_name" {
+ type = string
+ default = "apim-services"
+}
+
+variable "backend_rg_name" {
+ type = string
+ default = "apim-backend"
}
+
+variable "dns_domain" {
+ type = string
+}
+
+variable "acr_name" {
+ type = string
+ default = "gcacrapim"
+}
+
+variable "akv_name" {
+ type = string
+ default = "gc-apim-akv"
+}
+
+variable "aks_name" {
+ type = string
+ default = "apim-backend-aks"
+}
+
+variable "backend_endpoints" {
+ type = list(string)
+ default = ["apim-be-dev", "apim-be-stage", "apim-be-prod", ]
+}
\ No newline at end of file