Browse Source

adds terraform module for workload identity auth

Docs 3 years ago
parent
commit
580eb4e356

+ 22 - 0
terraform/azure/aks/main.tf

@@ -0,0 +1,22 @@
+
+resource "azurerm_kubernetes_cluster" "current" {
+  name                = var.cluster_name
+  resource_group_name = var.resource_group_name
+  location            = var.resource_group_location
+  dns_prefix          = var.dns_prefix
+
+  oidc_issuer_enabled = var.oidc_issuer_enabled
+
+  default_node_pool {
+    name       = var.default_node_pool_name
+    node_count = var.default_node_pool_node_count
+    vm_size    = var.default_node_pool_vm_size
+  }
+
+  identity {
+    type = "SystemAssigned"
+  }
+
+  tags = var.cluster_tags
+
+}

+ 10 - 0
terraform/azure/aks/output.tf

@@ -0,0 +1,10 @@
+
+output "cluster_issuer_url" {
+  value = azurerm_kubernetes_cluster.current.oidc_issuer_url
+}
+
+output "kube_config" {
+  value = azurerm_kubernetes_cluster.current.kube_config_raw
+
+  sensitive = true
+}

+ 13 - 0
terraform/azure/aks/providers.tf

@@ -0,0 +1,13 @@
+terraform {
+  required_providers {
+    azurerm = {
+      source = "hashicorp/azurerm"
+    }
+  }
+}
+
+provider "azurerm" {
+  features {}
+}
+
+

+ 48 - 0
terraform/azure/aks/variables.tf

@@ -0,0 +1,48 @@
+variable "cluster_name" {
+  type        = string
+  description = "The name of the Managed Kubernetes Cluster to create"
+}
+
+variable "resource_group_name" {
+  type        = string
+  description = "The Name which should be used for this Resource Group"
+}
+
+variable "resource_group_location" {
+  type        = string
+  description = "The Azure Region where the Resource Group should exist"
+}
+
+variable "dns_prefix" {
+  type        = string
+  description = "DNS prefix specified when creating the managed cluster"
+  default     = "api"
+}
+
+variable "oidc_issuer_enabled" {
+  type        = bool
+  description = "Enable or Disable the OIDC issuer URL"
+  default     = true
+}
+
+variable "default_node_pool_name" {
+  type        = string
+  description = " The name of the Default Node Pool which should be created within the Kubernetes Cluster"
+  default     = "default"
+}
+
+variable "default_node_pool_node_count" {
+  type        = number
+  description = " The initial number of nodes which should exist within this Node Pool"
+}
+
+variable "default_node_pool_vm_size" {
+  type        = string
+  description = " The SKU which should be used for the Virtual Machines used in this Node Pool"
+
+}
+
+variable "cluster_tags" {
+  type        = map(string)
+  description = "A mapping of tags to assign to the cluster"
+}

+ 42 - 0
terraform/azure/key-vault/main.tf

@@ -0,0 +1,42 @@
+
+resource "azurerm_key_vault" "current" {
+  name                        = var.key_vault_display_name
+  location                    = var.resource_group_location
+  resource_group_name         = var.resource_group_name
+  enabled_for_disk_encryption = true
+  tenant_id                   = var.tenant_id
+  soft_delete_retention_days  = 7
+  purge_protection_enabled    = false
+
+  sku_name = "standard"
+
+  access_policy {
+    tenant_id = var.tenant_id
+    object_id = var.client_object_id
+
+    key_permissions = [
+      "Get",
+    ]
+
+    secret_permissions = [
+      "Set",
+      "Get",
+      "Delete",
+      "Purge",
+      "Recover"
+    ]
+
+    storage_permissions = [
+      "Get",
+    ]
+  }
+  access_policy {
+    tenant_id = var.tenant_id
+    object_id = var.eso_sp_object_id
+
+    secret_permissions = [
+      "Get",
+    ]
+
+  }
+}

+ 3 - 0
terraform/azure/key-vault/output.tf

@@ -0,0 +1,3 @@
+output "key_vault_id" {
+  value = azurerm_key_vault.current.id
+}

+ 11 - 0
terraform/azure/key-vault/providers.tf

@@ -0,0 +1,11 @@
+terraform {
+  required_providers {
+    azurerm = {
+      source = "hashicorp/azurerm"
+    }
+  }
+}
+
+provider "azurerm" {
+  features {}
+}

+ 24 - 0
terraform/azure/key-vault/variables.tf

@@ -0,0 +1,24 @@
+variable "key_vault_display_name" {
+  type        = string
+  description = "Metadata name to use."
+}
+variable "resource_group_name" {
+  type        = string
+  description = "The Name which should be used for this Resource Group"
+}
+variable "resource_group_location" {
+  type        = string
+  description = "The Azure Region where the Resource Group should exist"
+}
+variable "tenant_id" {
+  type        = string
+  description = "Azure Tenant ID"
+}
+variable "client_object_id" {
+  type        = string
+  description = "The object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault"
+}
+variable "eso_sp_object_id" {
+  type        = string
+  description = "The object ID of the ESO service account"
+}

+ 61 - 0
terraform/azure/main.tf

@@ -0,0 +1,61 @@
+data "azurerm_client_config" "current" {}
+
+data "azurerm_subscription" "primary" {}
+
+module "test_resource_group" {
+  source = "./resource-group"
+
+  resource_group_name     = var.resource_group_name
+  resource_group_location = var.resource_group_location
+}
+
+module "test_sp" {
+  source = "./service-principal"
+
+  application_display_name = var.application_display_name
+  application_owners       = [data.azurerm_client_config.current.object_id]
+  issuer                   = module.test_aks.cluster_issuer_url
+  subject                  = "system:serviceaccount:${var.sa_namespace}:${var.sa_name}"
+}
+
+module "test_key_vault" {
+  source = "./key-vault"
+
+  key_vault_display_name  = var.key_vault_display_name
+  resource_group_location = var.resource_group_location
+  resource_group_name     = var.resource_group_name
+  tenant_id               = data.azurerm_client_config.current.tenant_id
+  client_object_id        = data.azurerm_client_config.current.object_id
+  eso_sp_object_id        = module.test_sp.sp_object_id
+}
+
+module "test_workload_identity" {
+  source = "./workload-identity"
+
+  tenant_id = data.azurerm_client_config.current.tenant_id
+  tags      = var.cluster_tags
+
+}
+
+module "test_aks" {
+  source = "./aks"
+
+  cluster_name                 = var.cluster_name
+  resource_group_name          = var.resource_group_name
+  resource_group_location      = var.resource_group_location
+  default_node_pool_node_count = var.default_node_pool_node_count
+  default_node_pool_vm_size    = var.default_node_pool_vm_size
+  cluster_tags                 = var.cluster_tags
+}
+
+resource "azurerm_role_assignment" "current" {
+  scope                = data.azurerm_subscription.primary.id
+  role_definition_name = "Reader"
+  principal_id         = module.test_sp.sp_id
+}
+
+resource "azurerm_key_vault_secret" "test" {
+  name         = "secret-sauce"
+  value        = "szechuan"
+  key_vault_id = module.test_key_vault.key_vault_id
+}

+ 21 - 0
terraform/azure/providers.tf

@@ -0,0 +1,21 @@
+terraform {
+  required_providers {
+    azuread = {
+      source = "hashicorp/azuread"
+    }
+  }
+}
+
+provider "azurerm" {
+  features {}
+}
+
+provider "helm" {
+  kubernetes {
+    config_path = "~/.kube/config"
+  }
+}
+provider "kubernetes" {
+  config_path = "~/.kube/config"
+}
+

+ 4 - 0
terraform/azure/resource-group/main.tf

@@ -0,0 +1,4 @@
+resource "azurerm_resource_group" "current" {
+  name     = var.resource_group_name
+  location = var.resource_group_location
+}

+ 11 - 0
terraform/azure/resource-group/providers.tf

@@ -0,0 +1,11 @@
+terraform {
+  required_providers {
+    azurerm = {
+      source = "hashicorp/azurerm"
+    }
+  }
+}
+
+provider "azurerm" {
+  features {}
+}

+ 9 - 0
terraform/azure/resource-group/variables.tf

@@ -0,0 +1,9 @@
+variable "resource_group_name" {
+  type        = string
+  description = "The Name which should be used for this Resource Group"
+}
+
+variable "resource_group_location" {
+  type        = string
+  description = "The Azure Region where the Resource Group should exist"
+}

+ 31 - 0
terraform/azure/service-principal/main.tf

@@ -0,0 +1,31 @@
+resource "azuread_application" "current" {
+
+  display_name = var.application_display_name
+  owners       = var.application_owners
+}
+
+resource "azuread_service_principal" "current" {
+
+  application_id               = azuread_application.current.application_id
+  app_role_assignment_required = false
+  owners                       = var.application_owners
+  feature_tags {
+    enterprise = true
+    gallery    = true
+  }
+}
+
+resource "azuread_service_principal_password" "current" {
+
+  service_principal_id = azuread_service_principal.current.id
+}
+
+
+
+resource "azuread_application_federated_identity_credential" "example" {
+  application_object_id = azuread_application.current.object_id
+  display_name          = var.application_display_name
+  audiences             = var.audiences
+  issuer                = var.issuer
+  subject               = var.subject
+}

+ 9 - 0
terraform/azure/service-principal/output.tf

@@ -0,0 +1,9 @@
+output "application_id" {
+  value = azuread_application.current.application_id
+}
+output "sp_id" {
+  value = azuread_service_principal.current.id
+}
+output "sp_object_id" {
+  value = azuread_service_principal.current.object_id
+}

+ 11 - 0
terraform/azure/service-principal/providers.tf

@@ -0,0 +1,11 @@
+terraform {
+  required_providers {
+    azuread = {
+      source = "hashicorp/azuread"
+    }
+  }
+}
+
+provider "azurerm" {
+  features {}
+}

+ 17 - 0
terraform/azure/service-principal/variables.tf

@@ -0,0 +1,17 @@
+variable "application_display_name" {
+  type        = string
+  description = "Metadata name to use."
+}
+variable "application_owners" {
+  type = list(string)
+}
+variable "issuer" {
+  type = string
+}
+variable "audiences" {
+  type    = list(string)
+  default = ["api://AzureADTokenExchange"]
+}
+variable "subject" {
+  type = string
+}

+ 66 - 0
terraform/azure/variables.tf

@@ -0,0 +1,66 @@
+variable "cluster_name" {
+  type        = string
+  description = "The name of the Managed Kubernetes Cluster to create"
+  default     = "eso-cluster"
+}
+
+variable "resource_group_name" {
+  type        = string
+  description = "The Name which should be used for this Resource Group"
+  default     = "external-secrets-operator"
+}
+
+variable "resource_group_location" {
+  type        = string
+  description = "The Azure Region where the Resource Group should exist"
+  default     = "westeurope"
+}
+variable "application_display_name" {
+  type        = string
+  description = "Metadata name to use."
+  default     = "external-secrets-operator"
+}
+
+variable "dns_prefix" {
+  type        = string
+  description = "DNS prefix specified when creating the managed cluster"
+  default     = "eso"
+}
+
+variable "key_vault_display_name" {
+  type        = string
+  description = "The name of the Key Vault to create"
+  default     = "eso-testing"
+}
+
+variable "default_node_pool_name" {
+  type        = string
+  description = " The name of the Default Node Pool which should be created within the Kubernetes Cluster"
+  default     = "default"
+}
+
+variable "default_node_pool_node_count" {
+  type        = number
+  description = " The initial number of nodes which should exist within this Node Pool"
+  default     = 1
+}
+
+variable "default_node_pool_vm_size" {
+  type        = string
+  description = " The SKU which should be used for the Virtual Machines used in this Node Pool"
+  default     = "Standard_B2ms"
+}
+variable "sa_name" {
+  type    = string
+  default = "external-secrets-operator"
+}
+variable "sa_namespace" {
+  type        = string
+  description = "The namespace where the service account will be created"
+  default     = "external-secrets-operator"
+}
+variable "cluster_tags" {
+  type        = map(string)
+  description = "A mapping of tags to assign to the cluster"
+  default     = { cluster_name = "external-secrets-operator" }
+}

+ 23 - 0
terraform/azure/workload-identity/main.tf

@@ -0,0 +1,23 @@
+resource "kubernetes_namespace" "azure-workload-identity-system" {
+  metadata {
+    annotations = {
+      name = "azure-workload-identity-system"
+    }
+    name   = "azure-workload-identity-system"
+    labels = var.tags
+  }
+}
+
+resource "helm_release" "azure-workload-identity-system" {
+  name       = "workload-identity-webhook"
+  namespace  = "azure-workload-identity-system"
+  chart      = "workload-identity-webhook"
+  repository = "https://azure.github.io/azure-workload-identity/charts"
+  wait       = false
+  depends_on = [kubernetes_namespace.azure-workload-identity-system]
+
+  set {
+    name  = "azureTenantID"
+    value = var.tenant_id
+  }
+}

+ 5 - 0
terraform/azure/workload-identity/provider.tf

@@ -0,0 +1,5 @@
+provider "helm" {
+  kubernetes {
+    config_path = "~/.kube/config"
+  }
+}

+ 7 - 0
terraform/azure/workload-identity/variables.tf

@@ -0,0 +1,7 @@
+variable "tags" {
+  type = map(string)
+}
+variable "tenant_id" {
+  type        = string
+  description = "Azure Tenant ID"
+}