diff --git a/azure/terraform/stacks/acm-general/.terraform.lock.hcl b/azure/terraform/stacks/acm-general/.terraform.lock.hcl index 06bef88c..2a0c66f4 100644 --- a/azure/terraform/stacks/acm-general/.terraform.lock.hcl +++ b/azure/terraform/stacks/acm-general/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/azuread" { version = "3.0.2" constraints = "3.0.2" hashes = [ + "h1:Sbb9HgPsFPsY3Jv8Kn+eoyYXoWHLWcODr7Okh/V001k=", "h1:sYCyzbPpSYu2XDah8XqBUITQAfB0x4j4Twh6lw2C4CA=", "zh:16e724b80a9004c7978c30f69a73c98ff63eb8a03937dd44c2a8f0ea0438b7a3", "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", @@ -26,6 +27,7 @@ provider "registry.terraform.io/hashicorp/azurerm" { constraints = "4.9.0" hashes = [ "h1:PaXhZEEv2W1p1LArJ98yMnfXBPF1uJiAf+7s1JAcejE=", + "h1:wr5kXxC+9jdgEfiEPRUmM4qM6tSgm84Re75ZwQNkdtI=", "zh:09c17cb67e3f4c2984648ee8592645c77c5f2f1a2902dbb8de340e2ed0ebfa56", "zh:13f3f912cd7c61a7d8e9046425b919e9fae8477919a6d9d55d8b3a1ca0f49e38", "zh:2f361f1e16a8e93834d26fd3f5df82e6f91fd20d4c5af70510cbf607d301ec5a", diff --git a/azure/terraform/stacks/acm-general/external-dns.tf b/azure/terraform/stacks/acm-general/external-dns.tf index c8cbb2fd..6bd103f8 100644 --- a/azure/terraform/stacks/acm-general/external-dns.tf +++ b/azure/terraform/stacks/acm-general/external-dns.tf @@ -19,16 +19,33 @@ resource "azuread_service_principal_password" "externaldns" { service_principal_id = azuread_service_principal.externaldns.id } +resource "azuread_application_federated_identity_credential" "externaldns" { + application_id = azuread_application.externaldns.id + display_name = "acmapp-externaldns" + description = "ExternalDNS on the ACM application Kubernetes cluster" + audiences = ["api://AzureADTokenExchange"] + issuer = var.external_dns_oidc_issuer_url + subject = "system:serviceaccount:${var.external_dns_namespace}:externaldns" +} + resource "azurerm_role_assignment" "externaldns_reader" { - scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/dnszones/${var.public_domain_suffixes[0]}" + scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}" role_definition_name = "Reader" principal_id = azuread_service_principal.externaldns.object_id + + lifecycle { + create_before_destroy = true + } } resource "azurerm_role_assignment" "externaldns_contributor" { scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/dnszones/${var.public_domain_suffixes[0]}" - role_definition_name = "Contributor" + role_definition_name = "DNS Zone Contributor" principal_id = azuread_service_principal.externaldns.object_id + + lifecycle { + create_before_destroy = true + } } output "tenant_id" { diff --git a/azure/terraform/stacks/acm-general/variables.tf b/azure/terraform/stacks/acm-general/variables.tf index 9ffe63b6..13f3a7ef 100644 --- a/azure/terraform/stacks/acm-general/variables.tf +++ b/azure/terraform/stacks/acm-general/variables.tf @@ -21,6 +21,12 @@ variable "external_dns_namespace" { default = "externaldns" } +variable "external_dns_oidc_issuer_url" { + type = string + description = "Public Kubernetes service account OIDC issuer used by ExternalDNS" + default = "https://k8s-oidc.acmuic.org" +} + variable "resource_group_name" { type = string description = "Specifies the name of the resource group that resources should be deployed into" diff --git a/azure/terraform/stacks/vault-injector/.terraform.lock.hcl b/azure/terraform/stacks/vault-injector/.terraform.lock.hcl index 84a76c26..e67c6c43 100644 --- a/azure/terraform/stacks/vault-injector/.terraform.lock.hcl +++ b/azure/terraform/stacks/vault-injector/.terraform.lock.hcl @@ -6,6 +6,7 @@ provider "registry.terraform.io/hashicorp/vault" { constraints = "3.19.0" hashes = [ "h1:PRAF8HdRK4hziAEjbWFRMjVftXU7QEyF3xMGXQELS4o=", + "h1:PqOYbId3i5LhvNm9BBQJklldEMNPoO/Fmn2hph0vMP0=", "zh:2571ca03777afcb70d51d7f591bfa0bf770bbcc93bb87563ec295b17a9b21947", "zh:25d096ab433e4eb5ed0f17f82beb661681c6abac93df35c15d5adf26da822709", "zh:33776aa50d597448539251b4b706b4dbaf599ebee47a4244361400f93cd10986", diff --git a/azure/terraform/stacks/vault-injector/external_dns.tf b/azure/terraform/stacks/vault-injector/external_dns.tf index d2715b29..3d7f1593 100644 --- a/azure/terraform/stacks/vault-injector/external_dns.tf +++ b/azure/terraform/stacks/vault-injector/external_dns.tf @@ -3,7 +3,7 @@ resource "vault_kv_secret_v2" "externaldns_keyid" { name = "externaldns/service_account" data_json = jsonencode( { - aadClientId = data.terraform_remote_state.acm_general.outputs.externaldns_sp_appid, + aadClientId = data.terraform_remote_state.acm_general.outputs.externaldns_sp_clientid, aadClientSecret = data.terraform_remote_state.acm_general.outputs.externaldns_sp_password resourceGroup = data.terraform_remote_state.acm_general.outputs.default_resource_group subscriptionId = data.terraform_remote_state.acm_general.outputs.subscription_id diff --git a/kubernetes/argocd/stacks/common/externaldns.yml b/kubernetes/argocd/stacks/common/externaldns.yml index 7d23b4cd..cc4b828c 100644 --- a/kubernetes/argocd/stacks/common/externaldns.yml +++ b/kubernetes/argocd/stacks/common/externaldns.yml @@ -11,7 +11,7 @@ spec: server: 'https://kubernetes.default.svc' sources: - repoURL: 'https://kubernetes-sigs.github.io/external-dns/' - targetRevision: 1.13.1 + targetRevision: 1.23.0 chart: external-dns helm: valueFiles: diff --git a/kubernetes/argocd/stacks/externaldns/externaldns.yml b/kubernetes/argocd/stacks/externaldns/externaldns.yml index 8f30a6d2..c009061a 100644 --- a/kubernetes/argocd/stacks/externaldns/externaldns.yml +++ b/kubernetes/argocd/stacks/externaldns/externaldns.yml @@ -4,22 +4,16 @@ kind: Namespace metadata: name: externaldns --- -apiVersion: cert-manager.io/v1 -kind: Certificate +apiVersion: v1 +kind: ConfigMap metadata: - name: externaldns-vault-cert + name: externaldns-azure-config namespace: externaldns -spec: - dnsNames: - - "externaldns.acmuic.org" - - "*.externaldns.svc" - ipAddresses: - - 127.0.0.1 - usages: - - server auth - - digital signature - - key encipherment - secretName: externaldns-vault-cert - issuerRef: - kind: ClusterIssuer - name: acmuic-self-ca +data: + azure.json: | + { + "tenantId": "cad5e02f-bae4-42d6-a06e-4377dd3e386f", + "subscriptionId": "2f98793b-7e2f-4f03-ac5b-7b2ec934dcd7", + "resourceGroup": "acm-general", + "useWorkloadIdentityExtension": true + } diff --git a/kubernetes/argocd/stacks/externaldns/values.yml b/kubernetes/argocd/stacks/externaldns/values.yml index ce5c8640..eaf5a8a3 100644 --- a/kubernetes/argocd/stacks/externaldns/values.yml +++ b/kubernetes/argocd/stacks/externaldns/values.yml @@ -1,24 +1,33 @@ --- -provider: azure +provider: + name: azure serviceAccount: name: externaldns -podAnnotations: - vault.hashicorp.com/agent-inject: 'true' - vault.hashicorp.com/role: 'externaldns' - vault.hashicorp.com/agent-inject-secret-azure.json: 'kv/externaldns/service_account' - vault.hashicorp.com/tls-secret: 'externaldns-vault-cert' - vault.hashicorp.com/ca-cert: '/vault/tls/ca.crt' - vault.hashicorp.com/agent-inject-template-azure.json: | - {{- with secret "kv/externaldns/service_account" -}} - { - "tenantId" : "{{ .Data.data.tenantId }}", - "subscriptionId" : "{{ .Data.data.subscriptionId }}", - "resourceGroup" : "{{ .Data.data.resourceGroup }}", - "aadClientId" : "{{ .Data.data.aadClientId }}", - "aadClientSecret" : "{{ .Data.data.aadClientSecret }}" - } - {{- end }} -extraArgs: ["--azure-config-file=/vault/secrets/azure.json"] + annotations: + azure.workload.identity/client-id: f995b4bc-00a0-4912-9a1a-da9f74407cb8 + azure.workload.identity/tenant-id: cad5e02f-bae4-42d6-a06e-4377dd3e386f +podLabels: + azure.workload.identity/use: "true" +extraVolumes: + - name: azure-config + configMap: + name: externaldns-azure-config +extraVolumeMounts: + - name: azure-config + mountPath: /etc/kubernetes + readOnly: true +extraArgs: + azure-config-file: /etc/kubernetes/azure.json +policy: upsert-only +registry: txt +# Preserve ownership of records created by the existing controller. +txtOwnerId: default +domainFilters: + - acmuic.org +# ACME solver Ingresses must not publish the internal load balancer address. +labelFilter: acme.cert-manager.io/http01-solver!=true +# Keep the target annotations used by the existing IngressRoutes. +annotationPrefix: external-dns.alpha.kubernetes.io/ sources: - service - ingress