_This issue was originally opened by @flobeier as hashicorp/terraform#24116. It was migrated here as a result of the provider split. The original body of the issue is below._
Terraform v0.12.20
+ provider.azurerm v1.42.0
I already set the credentials for the service principal via environment variables (ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_SUBSCRIPTION_ID, ARM_TENANT_ID). It would be nice if azurerm_kubernetes_cluster could use them for its service_principal block so one wouldn't need to set additional variables with the same content.
I used the azurerm_client_config data source to get the client_id. However, it doesn't provide the client_secret, so I still have to set an additional environment variable for it.
Make the service_principal block of azurerm_kubernetes_cluster use the same environment variables that the azurerm provider uses. An alternate solution would be to add client_secret to the azurerm_client_config data source so one could get the client secret of the service principal from it.
See https://docs.microsoft.com/en-us/azure/aks/kubernetes-service-principal#additional-considerations. Although it's appealing, it would be against Microsoft's advice:
When using AKS and Azure AD service principals, keep the following considerations in mind.
- The service principal for Kubernetes is a part of the cluster configuration. However, don't use the identity to deploy the cluster.
@aristosvo thanks for pointing that out to me. Although one should read the documentation, I feel like the Terraform docs could be updated with a little note to include this.
My original proposal is now obsolete, but maybe two environment variables like "AKS_SERVICE_PRINCIPAL_ID" and "AKS_SERVICE_PRINCIPAL_SECRET" could be used for configuring the service principal.
My own prefered way of configuring this is using a Key Vault to store all this information to configure it once and never look back:
resource "azurerm_key_vault" "kv-core" {
name = var.kv
location = var.location
resource_group_name = var.rg
enabled_for_template_deployment = true
tenant_id = var.tenant_id
sku_name = "standard"
network_acls {
default_action = "Deny"
// ip's who can access your service principal secret etc
ip_rules = ["${var.ip}/32"]
}
// Permissions for DevOps Pipeline
access_policy {
tenant_id = var.tenant_id
object_id = var.devops_sp
secret_permissions = ["delete", "get", "list", "set"]
}
// Permissions for administrators to edit secrets
access_policy {
tenant_id = var.tenant_id
object_id = var.admin_group
secret_permissions = ["delete", "get", "list", "set"]
}
}
// Initiate a local.key_vault_id without direct dependencies to prevent a dependency of the secrets on the Key Vault provisioning
// It may cause a delete of the old and creation of a new AKS cluster without any change in the secret values
locals {
key_vault_id = "/subscriptions/${var.subscription}/resourceGroups/${var.rg}/providers/Microsoft.KeyVault/vaults/${var.kv}"
}
data "azurerm_key_vault_secret" "k8s-client-secret" {
name = "k8s-client-secret"
key_vault_id = local.key_vault_id
}
data "azurerm_key_vault_secret" "k8s-service_principal" {
name = "k8s-service_principal"
key_vault_id = local.key_vault_id
}
resource "azurerm_kubernetes_cluster" "aks" {
...
service_principal {
client_id = data.azurerm_key_vault_secret.k8s-service_principal.value
client_secret = data.azurerm_key_vault_secret.k8s-client-secret.value
}
}
In the examples Microsoft provides the service principal values end up as input variables for TerraForm, which is also fine if you work with environment variables anyway. Using TF_VAR_ followed by the name of a declared variable makes your experience as expected.
hi @flobeier
Thanks for opening this issue.
Azure Kubernetes Service is gradually moving away from using a Service Principal (which we represent in the service_principal block) to using a Managed Identity (via the identity block).
Whilst Terraform could look to source some fields (as in this case the Client ID and Client Secret) from an Environment Variable - this wouldn't be obvious to most users - as such we'd instead suggest doing this using Environment Variables using a Variable - for example:
$ TF_VAR_second_client_id=0000.. terraform apply
variable "second_client_id" {}
output "client_id" {
value = var.second_client_id
}
As the Service Principal block is being superseded by AKS in the future - and we tend to avoid sourcing values for nested blocks from Environment Variables - unfortunately this isn't something we plan to ship and as such I'm going to close this issue for the moment.
Thanks!
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!