microsoft / terraform-provider-azuredevops

Terraform Azure DevOps provider
https://www.terraform.io/docs/providers/azuredevops/
MIT License
372 stars 260 forks source link

serviceendpoint_kubernetes service_account auth type doesn't accept untrusted certs #1039

Open RickardTaran opened 2 months ago

RickardTaran commented 2 months ago

I can't set accept_untrusted_certs = true for auth type = service_account.

The serviceendpoint_kubernetes resource has 3 auth types. 2 of them being service_account and KubeConfig. Each auth type comes with it's own block for configuration. The block for KubeConfig includes a setting for accept_untrusted_certs.

The same setting does not exist in the block for service_account. Because of this, after creating the service connection, I have to manually go to dev.azure.com to set this.

Community Note

Terraform (and Azure DevOps Provider) Version

Terraform v1.7.5 microsoft/azuredevops 1.0.1

Affected Resource(s)

Terraform Configuration Files

data "azurerm_kubernetes_cluster" "cluster" {
  name                = local.aks_name
  resource_group_name = local.rg_name
}

resource "kubernetes_service_account" "service_account" {
  metadata {
    name = var.service_account_name
    namespace = var.namespace
  }
}

resource "kubernetes_secret" "token" {
  metadata {
    annotations = {
      "kubernetes.io/service-account.name" = var.service_account_name
    }
    generate_name = "${var.service_account_name}-token-"
    namespace = var.namespace
  }
  type = "kubernetes.io/service-account-token"
  wait_for_service_account_token = true
}

resource "kubernetes_cluster_role_binding" "example" {
  metadata {
    name = "${var.service_account_name}-cluster-admin-binding"
  }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "cluster-admin"
  }
  subject {
    kind      = "ServiceAccount"
    name      = var.service_account_name
    namespace = var.namespace
  }
}

resource "azuredevops_serviceendpoint_kubernetes" "svc_connection" {
  project_id            = local.const.project_id
  service_endpoint_name = local.aks_name
  apiserver_url         = data.azurerm_kubernetes_cluster.cluster.kube_config[0].host
  authorization_type    = "ServiceAccount"

  service_account {
    token   = kubernetes_secret.token.data.token
    ca_cert = kubernetes_secret.token.data["ca.crt"]
    # Here is the issue
  }
}

resource "azuredevops_environment_resource_kubernetes" "namespaces" {
  for_each            = toset(local.const.namespaces)
  project_id          = local.const.project_id
  environment_id      = local.const.environment_id
  service_endpoint_id = azuredevops_serviceendpoint_kubernetes.svc_connection.id
  name                = "${local.region_short}-${each.value}"
  namespace           = each.value
  cluster_name        = local.aks_name
}

Debug Output

N/A apply runs fine. Issue observed in azure devops

Panic Output

N/A

Expected Behavior

I need to be able to set accept_untrusted_certs for

authorization_type    = "ServiceAccount"

This setting exists for

authorization_type    = "Kubeconfig"

Actual Behavior

The service connection is created successfully along with the azuredevops_environment_resource_kubernetes resources. However, when I open up the resources in the deployment environment, an error comes up that the associated service connection doesn't have access. This error is misleading, and when I try "validate and check" I just have to check the box for "Accept untrusted certificates". Changing this in azure devops also does not affect state for the template.

Steps to Reproduce

1) create an aks cluster 2) use the above template code to create a

Important Factoids

I'm using the service account authentication type instead of AzureSubscription. We're using the Azure AD RBAC integration for AKS and have disabled local accounts. This breaks the AzureSubscription auth type.

References

xuzhang3 commented 1 month ago

@RickardTaran do mean you need check box(untrusted cert) in the k8s-env config page? image

RickardTaran commented 1 month ago

That's what I have to do in ADO to fix this. I would just like to be able to set that in the azuredevops_serviceendpoint_kubernetes resource

This setting does exist for authorization_type = "KubeConfig" but not for authorization_type = "ServiceAccount"

After applying the template, going into dev.azure.com and clicking that box does solve the issue. But I can not set that in terraform.

xuzhang3 commented 1 month ago

@RickardTaran this feature is part of azuredevops_environment_resource_kubernetes not k8s service connection.

xuzhang3 commented 1 month ago

Untrusted certificate configuration is delegated to the k8s service connection though it is not available in portal web page but existed in the API.

RickardTaran commented 1 month ago

Not sure I follow. Is this something that's meant to be configured on the azuredevops_environment_resource_kubernetes resource instead of the service endpoint? I don't see the value in that schema either, bottom line would still be that I need a way to do this in terraform. Are you saying in the second comment that it is actually set with the service endpoint, just only through the API? That would make sense.

Using the rest API to get service endpoint info, looks like the acceptUntrustedCerts input descriptor doesn't have any properties.visibleRule...

"inputDescriptors": [
        {
          "description": "Trust Certificate",
          "groupName": null,
          "id": "acceptUntrustedCerts",
          "inputMode": "checkBox",
          "isConfidential": false,
          "name": "AcceptUntrustedCerts",
          "properties": null,
          "type": null,
          "useInDefaultDescription": false,
          "validation": {
            "dataType": "string"
          },
          "valueHint": null
        },
        ...
]

Regardless, need a way to do this in terraform

xuzhang3 commented 1 month ago

@RickardTaran by track the API request, this property is managed by service connection though its not available in the service connection managed page. image