Skip to content

Commit

Permalink
feat(aks): Split workload identity into init and configuration (#345)
Browse files Browse the repository at this point in the history
* kubernetes_workload_identity_init starts

* kubernetes_workload_identity_configuration

* minor fix

* fix outputs

* fix docs

* removed variables not needed

* pre-commit fixs
  • Loading branch information
diegolagospagopa authored Sep 2, 2024
1 parent 2334835 commit 73602bc
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# kubernetes pod identity
# kubernetes workload identity configuration

Module that allows the creation of a workload identity.
Module that allows the configuration of a workload identity.

To enable workload identity this others resources are created:
To enable workload identity this others resources are created/configured:

* user managed identity
* user managed identity (already present into the system)
* federated identity
* key vault policy
* service account with user managed client id
Expand Down Expand Up @@ -54,9 +54,9 @@ No modules.
| [azurerm_federated_identity_credential.workload_identity_federation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
| [azurerm_key_vault_access_policy.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy) | resource |
| [azurerm_key_vault_secret.workload_identity_client_id](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
| [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [kubernetes_service_account_v1.workload_identity_sa](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account_v1) | resource |
| [azurerm_kubernetes_cluster.aks](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_cluster) | data source |
| [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity) | data source |

## Inputs

Expand All @@ -73,9 +73,8 @@ No modules.
| <a name="input_service_account_configuration_enabled"></a> [service\_account\_configuration\_enabled](#input\_service\_account\_configuration\_enabled) | (Optional) Enabled the service account configuration | `string` | `true` | no |
| <a name="input_service_account_image_pull_secret_names"></a> [service\_account\_image\_pull\_secret\_names](#input\_service\_account\_image\_pull\_secret\_names) | (Optional) Sets of image pull secert names | `set(string)` | `[]` | no |
| <a name="input_service_account_labels"></a> [service\_account\_labels](#input\_service\_account\_labels) | (Optional) More Labels for service account | `map(string)` | `{}` | no |
| <a name="input_workload_identity_full_name"></a> [workload\_identity\_full\_name](#input\_workload\_identity\_full\_name) | (Optional) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created. | `string` | `null` | no |
| <a name="input_workload_identity_name"></a> [workload\_identity\_name](#input\_workload\_identity\_name) | (Required) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created. | `string` | n/a | yes |
| <a name="input_workload_identity_resource_group_name"></a> [workload\_identity\_resource\_group\_name](#input\_workload\_identity\_resource\_group\_name) | (Required) Resource group for the workload identity. | `string` | n/a | yes |
| <a name="input_workload_name_prefix"></a> [workload\_name\_prefix](#input\_workload\_name\_prefix) | (Required) The name prefix of the user assigned identity and Workload identity. Changing this forces a new identity to be created. | `string` | n/a | yes |

## Outputs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@ data "azurerm_kubernetes_cluster" "aks" {
resource_group_name = var.aks_resource_group_name
}

#------------------------------------------------------------------------------
resource "azurerm_user_assigned_identity" "this" {
name = local.workload_identity_name

data "azurerm_user_assigned_identity" "this" {
name = var.workload_identity_name
resource_group_name = var.workload_identity_resource_group_name
location = data.azurerm_kubernetes_cluster.aks.location
}

#------------------------------------------------------------------------------

resource "azurerm_federated_identity_credential" "workload_identity_federation" {
name = local.workload_identity_name
name = var.workload_identity_name
resource_group_name = var.workload_identity_resource_group_name
audience = ["api://AzureADTokenExchange"]
issuer = data.azurerm_kubernetes_cluster.aks.oidc_issuer_url
parent_id = azurerm_user_assigned_identity.this.id
subject = "system:serviceaccount:${var.namespace}:${local.workload_identity_name}"
parent_id = data.azurerm_user_assigned_identity.this.id
subject = "system:serviceaccount:${var.namespace}:${var.workload_identity_name}"

depends_on = [
data.azurerm_user_assigned_identity.this
]
}

#
Expand All @@ -26,11 +29,11 @@ resource "azurerm_federated_identity_credential" "workload_identity_federation"
resource "kubernetes_service_account_v1" "workload_identity_sa" {
count = var.service_account_configuration_enabled ? 1 : 0
metadata {
name = local.workload_identity_name
name = var.workload_identity_name
namespace = var.namespace
annotations = merge(
{
"azure.workload.identity/client-id" = azurerm_user_assigned_identity.this.client_id
"azure.workload.identity/client-id" = data.azurerm_user_assigned_identity.this.client_id
},
var.service_account_annotations
)
Expand All @@ -44,6 +47,10 @@ resource "kubernetes_service_account_v1" "workload_identity_sa" {
name = image_pull_secret.key
}
}

depends_on = [
data.azurerm_user_assigned_identity.this
]
}

#
Expand All @@ -52,22 +59,22 @@ resource "kubernetes_service_account_v1" "workload_identity_sa" {

resource "azurerm_key_vault_access_policy" "this" {
key_vault_id = var.key_vault_id
tenant_id = azurerm_user_assigned_identity.this.tenant_id
tenant_id = data.azurerm_user_assigned_identity.this.tenant_id

# The object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault.
object_id = azurerm_user_assigned_identity.this.principal_id
object_id = data.azurerm_user_assigned_identity.this.principal_id

certificate_permissions = var.key_vault_certificate_permissions
key_permissions = var.key_vault_key_permissions
secret_permissions = var.key_vault_secret_permissions

depends_on = [
azurerm_user_assigned_identity.this
data.azurerm_user_assigned_identity.this
]
}

resource "azurerm_key_vault_secret" "workload_identity_client_id" {
key_vault_id = var.key_vault_id
name = "${local.workload_identity_name}-client-id"
value = azurerm_user_assigned_identity.this.client_id
name = "${var.workload_identity_name}-client-id"
value = data.azurerm_user_assigned_identity.this.client_id
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
output "user_assigned_identity_id" {
value = azurerm_user_assigned_identity.this.id
value = data.azurerm_user_assigned_identity.this.id
}

output "user_assigned_identity_name" {
value = azurerm_user_assigned_identity.this.name
value = data.azurerm_user_assigned_identity.this.name
}

output "user_assigned_identity_resource_group_name" {
value = azurerm_user_assigned_identity.this.resource_group_name
value = data.azurerm_user_assigned_identity.this.resource_group_name
}

output "user_assigned_identity_client_id" {
value = azurerm_user_assigned_identity.this.client_id
value = data.azurerm_user_assigned_identity.this.client_id
}

output "workload_identity_client_id" {
value = azurerm_user_assigned_identity.this.client_id
output "user_assigned_identity_principal_id" {
value = data.azurerm_user_assigned_identity.this.principal_id
}

output "user_assigned_identity_principal_id" {
value = azurerm_user_assigned_identity.this.principal_id
output "workload_identity_client_id" {
value = data.azurerm_user_assigned_identity.this.client_id
}

output "workload_identity_principal_id" {
value = azurerm_user_assigned_identity.this.principal_id
value = data.azurerm_user_assigned_identity.this.principal_id
}

output "workload_identity_service_account_name" {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
locals {
workload_identity_name = var.workload_identity_full_name != null ? var.workload_identity_full_name : "${var.workload_name_prefix}-workload-identity"
}

variable "workload_name_prefix" {
type = string
description = "(Required) The name prefix of the user assigned identity and Workload identity. Changing this forces a new identity to be created."
}

variable "workload_identity_full_name" {
variable "workload_identity_name" {
type = string
description = "(Optional) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created."
default = null
description = "(Required) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created."
}

variable "workload_identity_resource_group_name" {
Expand Down
File renamed without changes.
65 changes: 65 additions & 0 deletions kubernetes_workload_identity_init/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Kubernetes Workload Identity init

Module that allows the creation of a workload identity.

To enable workload identity this others resources are created:

* User managed identity
* lock (this allow to avoid to delete the managed identity and change the client used by apps)

## How to use it

```hcl
module "workload_identity" {
source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//kubernetes_workload_identity_init?ref=<your version>"
workload_name_prefix = var.domain
workload_identity_resource_group_name = data.azurerm_kubernetes_cluster.aks.resource_group_name
workload_identity_location = var.location
}
```

<!-- markdownlint-disable -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~>3.110 |
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | ~> 2.30.0 |
| <a name="requirement_null"></a> [null](#requirement\_null) | ~> 3.2 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_management_lock.managed_identity_lock](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock) | resource |
| [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_enable_lock"></a> [enable\_lock](#input\_enable\_lock) | Allow to enable of disable lock for managed identity | `bool` | `true` | no |
| <a name="input_workload_identity_full_name"></a> [workload\_identity\_full\_name](#input\_workload\_identity\_full\_name) | (Optional) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created. | `string` | `null` | no |
| <a name="input_workload_identity_location"></a> [workload\_identity\_location](#input\_workload\_identity\_location) | (Required) The Azure Region where the User Assigned Identity should exist. Changing this forces a new User Assigned Identity to be created. | `string` | n/a | yes |
| <a name="input_workload_identity_resource_group_name"></a> [workload\_identity\_resource\_group\_name](#input\_workload\_identity\_resource\_group\_name) | (Required) Specifies the name of the Resource Group within which this User Assigned Identity should exist. Changing this forces a new User Assigned Identity to be created. | `string` | n/a | yes |
| <a name="input_workload_name_prefix"></a> [workload\_name\_prefix](#input\_workload\_name\_prefix) | (Required) The name prefix of the user assigned identity and Workload identity. Changing this forces a new identity to be created. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_user_assigned_identity_client_id"></a> [user\_assigned\_identity\_client\_id](#output\_user\_assigned\_identity\_client\_id) | n/a |
| <a name="output_user_assigned_identity_id"></a> [user\_assigned\_identity\_id](#output\_user\_assigned\_identity\_id) | n/a |
| <a name="output_user_assigned_identity_name"></a> [user\_assigned\_identity\_name](#output\_user\_assigned\_identity\_name) | n/a |
| <a name="output_user_assigned_identity_principal_id"></a> [user\_assigned\_identity\_principal\_id](#output\_user\_assigned\_identity\_principal\_id) | n/a |
| <a name="output_user_assigned_identity_resource_group_name"></a> [user\_assigned\_identity\_resource\_group\_name](#output\_user\_assigned\_identity\_resource\_group\_name) | n/a |
| <a name="output_workload_identity_client_id"></a> [workload\_identity\_client\_id](#output\_workload\_identity\_client\_id) | n/a |
| <a name="output_workload_identity_principal_id"></a> [workload\_identity\_principal\_id](#output\_workload\_identity\_principal\_id) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
15 changes: 15 additions & 0 deletions kubernetes_workload_identity_init/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "azurerm_user_assigned_identity" "this" {
name = local.workload_identity_name

resource_group_name = var.workload_identity_resource_group_name
location = var.workload_identity_location
}

resource "azurerm_management_lock" "managed_identity_lock" {
count = var.enable_lock ? 1 : 0

name = local.workload_identity_name
scope = azurerm_user_assigned_identity.this.id
lock_level = "CanNotDelete"
notes = "Locked because it's needed by terraform"
}
28 changes: 28 additions & 0 deletions kubernetes_workload_identity_init/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
output "user_assigned_identity_id" {
value = azurerm_user_assigned_identity.this.id
}

output "user_assigned_identity_name" {
value = azurerm_user_assigned_identity.this.name
}

output "user_assigned_identity_resource_group_name" {
value = azurerm_user_assigned_identity.this.resource_group_name
}

output "user_assigned_identity_principal_id" {
value = azurerm_user_assigned_identity.this.principal_id
}

output "user_assigned_identity_client_id" {
value = azurerm_user_assigned_identity.this.client_id
}

output "workload_identity_client_id" {
value = azurerm_user_assigned_identity.this.client_id
}

output "workload_identity_principal_id" {
value = azurerm_user_assigned_identity.this.principal_id
}

30 changes: 30 additions & 0 deletions kubernetes_workload_identity_init/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
locals {
workload_identity_name = var.workload_identity_full_name != null ? var.workload_identity_full_name : "${var.workload_name_prefix}-workload-identity"
}

variable "workload_name_prefix" {
type = string
description = "(Required) The name prefix of the user assigned identity and Workload identity. Changing this forces a new identity to be created."
}

variable "workload_identity_full_name" {
type = string
description = "(Optional) The full name for the user assigned identity and Workload identity. Changing this forces a new identity to be created."
default = null
}

variable "workload_identity_resource_group_name" {
type = string
description = "(Required) Specifies the name of the Resource Group within which this User Assigned Identity should exist. Changing this forces a new User Assigned Identity to be created."
}

variable "workload_identity_location" {
type = string
description = "(Required) The Azure Region where the User Assigned Identity should exist. Changing this forces a new User Assigned Identity to be created."
}

variable "enable_lock" {
type = bool
description = "Allow to enable of disable lock for managed identity"
default = true
}
18 changes: 18 additions & 0 deletions kubernetes_workload_identity_init/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
terraform {
required_version = ">= 1.5.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.110"
}
null = {
source = "hashicorp/null"
version = "~> 3.2"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30.0"
}
}
}

0 comments on commit 73602bc

Please sign in to comment.