-
Notifications
You must be signed in to change notification settings - Fork 988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Authenticate kubernetes
provider to AKS using Terraform Cloud Dynamic Credentials for Azure
#2603
Comments
Hi, I just want to make sure that I understand what exactly is the ask here. So would using a configuration like you presented in Option 2, which would work, not exactly meet your expectations? |
@alexsomesan Thanks for the reply - Option 2 would totally work (if that worked) to meet the need, and at that point, I would propose that this issue would be solved with just a documentation update that showed a workable solution using the Option 1 would also meet the need, and would rhyme more with how the Either way it were to be accomplished, the ultimate goal is that the |
I have a somewhat hacky workaround for this (in my case, using a GitHub Actions ID token as the credential): locals {
github_id_token_azure_filename = "/tmp/.github-id-token-azure"
}
data "azurerm_client_config" "current" {
}
data "azurerm_kubernetes_cluster" "aks" {
name = var.aks_name
resource_group_name = var.aks_resource_group
}
data "http" "github_id_token_azure" {
url = "${var.github_id_token_request_url}&audience=api://AzureADTokenExchange"
request_headers = {
Authorization = "bearer ${var.github_id_token_request_token}"
Accept = "application/json; api-version=2.0"
}
}
locals {
kubernetes_credentials = {
host = one(data.azurerm_kubernetes_cluster.aks.kube_config).host
cluster_ca_certificate = base64decode(
one(data.azurerm_kubernetes_cluster.aks.kube_config)
.cluster_ca_certificate
)
exec_api_version = "client.authentication.k8s.io/v1beta1"
exec_command = "/bin/bash"
exec_args = [
"-c",
join(" ", [
"echo \"${jsondecode(data.http.github_id_token_azure.response_body).value}\"",
"> ${local.github_id_token_azure_filename}",
"&&",
"kubelogin",
"get-token",
"--login",
"workloadidentity",
"--server-id",
"6dae42f8-4368-4678-94ff-3960e28e3630", # See https://azure.github.io/kubelogin/concepts/aks.html
])
]
exec_env = {
AZURE_AUTHORITY_HOST = "https://login.microsoftonline.com/"
AZURE_TENANT_ID = data.azurerm_client_config.current.tenant_id
AZURE_CLIENT_ID = data.azurerm_client_config.current.client_id
AZURE_FEDERATED_TOKEN_FILE = local.github_id_token_azure_filename
}
}
}
provider "kubernetes" {
host = local.kubernetes_credentials.host
cluster_ca_certificate = local.kubernetes_credentials.cluster_ca_certificate
exec {
api_version = local.kubernetes_credentials.exec_api_version
command = local.kubernetes_credentials.exec_command
args = local.kubernetes_credentials.exec_args
env = local.kubernetes_credentials.exec_env
}
} These two Terraform variables are populated by the environment variables (I do this in Terragrunt):
The reason it's as ugly as it is is that kubelogin get-token requires the federated ID token to be written to a file beforehand, so we need a way to force Terraform to write that file every time it starts the provider - including during the I can't think of a way of doing this that doesn't involve a shell command - feel free to propose better ways if you can think of them! It would be great if there was a cleaner way to do this. I suppose the question is - do we expect the kubernetes provider to provide a wrapper for this logic for all major cloud platforms, or should this functionality be implemented upstream by the cloud platform's client-go plugin? For instance, if I can't find any existing issues suggesting this - want me to create one? |
Rereading your issue, it's weird that there's already a valid JWT with the correct audience - which is the hard part - but it isn't working with kubelogin. That warrants some investigation. I've had issues before if I use an ID token that was issued before the AKS cluster was created. I have a theory that there's some logic somewhere that checks that the |
I don't know if this is related, but for me it was straight forward. I have seen many (for me) complex setups like https://github.com/neumanndaniel/terraform/blob/master/modules/kubelogin/main.tf or the proposed options here. In my case, I only had to
In Terraform I only had to define the following provider config
and I was able to apply this example
Hope this might help others, at least for local deployments. But I expect that if you convert the kubeconfig via |
Description
One-liner:
kubernetes
Terraform provider to work with Entra-enabled AKS without managing any secrets (just OIDC federations).Scenario:
azurerm
andkubernetes
providers, for onboarding new apps/apis into AKS cluster. (azurerm_user_assigned_identity
,kubernetes_namespace_v1
,kubernetes_service_account_v1
, etc.)azurerm
provider perfectlyOwner
role of the resource group where theazurerm
resources goAzure Kubernetes Service RBAC Cluster Admin
role, sufficient to make any changes through the Kubernetes API of the AKS clusterManual version illustrating a similar idea:
Goal:
kubernetes
Terraform provider is able to take on the same identity being pulled in by theazurerm
provider, using that identity to call the AKS cluster's Kubernetes API when provisioningkubernetes_*
resourcesazurerm
provider federating via OIDC)Potential Terraform Configuration
I can imagine two ways to do this:
Option 1:
kubernetes
provider can be told to use the same Azure Dyamic Credentials as theazurerm
providerOption 2:
kubernetes
provider exchanges the TFC-provided OIDC token on its own:Notes:
kubelogin
to be available within the context of the Terraform run. We need a self-hosted TFC agent anyways, due to use of a private cluster, so the TFC-provided agents wouldn't have line-of-sight to the Kubernetes API, and have installedkubelogin
ourselves./home/tfc-agent/.tfc-agent/component/terraform/runs/{run-id-here}/tfc-azure-token
, with issuer ofhttps://app.terraform.io
and audience ofapi://AzureADTokenExchange
, but using that JWT withkubelogin
isn't workingkubelogin get-token
command as specified in mykubeconfig
afterkubelogin convert-kubeconfig -l azurecli
, I get a JWT with an issuer ofhttps://sts.windows.net/{my-tenant-id-here}/
and audience of6dae42f8-4368-4678-94ff-3960e28e3630
, which is that static Entra ID for the AKS OIDC application that is the same for every customer. I believe this JWT is what is being submitted with calls to the Kubernetes API.References
Community Note
The text was updated successfully, but these errors were encountered: