Skip to content

Commit 4f13722

Browse files
committed
Migrate azure to workload identity
Signed-off-by: osamamagdy <osamamagdy174@gmail.com>
1 parent d26fd0f commit 4f13722

12 files changed

+82
-115
lines changed

azure/README.md

+7-9
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ The documentation below is auto-generated to give insight on what's created via
114114

115115
| Name | Version |
116116
|------|---------|
117+
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | n/a |
117118
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.83.0 |
118119
| <a name="provider_http"></a> [http](#provider\_http) | 3.4.0 |
119120
| <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
@@ -126,6 +127,10 @@ No modules.
126127

127128
| Name | Type |
128129
|------|------|
130+
| [azuread_application.app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | resource |
131+
| [azuread_application_federated_identity_credential.app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential) | resource |
132+
| [azuread_service_principal.app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
133+
| [azuread_service_principal_password.app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal_password) | resource |
129134
| [azurerm_key_vault.vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource |
130135
| [azurerm_key_vault_access_policy.extra_identity_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy) | resource |
131136
| [azurerm_key_vault_access_policy.identity_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy) | resource |
@@ -135,11 +140,6 @@ No modules.
135140
| [azurerm_key_vault_secret.wrongsecret_3](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
136141
| [azurerm_kubernetes_cluster.cluster](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster) | resource |
137142
| [azurerm_resource_group.default](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
138-
| [azurerm_role_assignment.aks_extra_identity_operator](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
139-
| [azurerm_role_assignment.aks_identity_operator](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
140-
| [azurerm_role_assignment.aks_vm_contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
141-
| [azurerm_user_assigned_identity.aks_extra_pod_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
142-
| [azurerm_user_assigned_identity.aks_pod_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
143143
| [random_integer.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) | resource |
144144
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
145145
| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
@@ -158,12 +158,10 @@ No modules.
158158

159159
| Name | Description |
160160
|------|-------------|
161-
| <a name="output_aad_extra_pod_identity_client_id"></a> [aad\_extra\_pod\_identity\_client\_id](#output\_aad\_extra\_pod\_identity\_client\_id) | Client ID for the Managed Identity for AAD Pod Identity |
162-
| <a name="output_aad_extra_pod_identity_resource_id"></a> [aad\_extra\_pod\_identity\_resource\_id](#output\_aad\_extra\_pod\_identity\_resource\_id) | Resource ID for the Managed Identity for AAD Pod Identity |
163-
| <a name="output_aad_pod_identity_client_id"></a> [aad\_pod\_identity\_client\_id](#output\_aad\_pod\_identity\_client\_id) | Client ID for the Managed Identity for AAD Pod Identity |
164-
| <a name="output_aad_pod_identity_resource_id"></a> [aad\_pod\_identity\_resource\_id](#output\_aad\_pod\_identity\_resource\_id) | Resource ID for the Managed Identity for AAD Pod Identity |
161+
| <a name="output_app_client_id"></a> [app\_client\_id](#output\_app\_client\_id) | n/a |
165162
| <a name="output_cluster_name"></a> [cluster\_name](#output\_cluster\_name) | AKS Cluster name |
166163
| <a name="output_key_vault_url"></a> [key\_vault\_url](#output\_key\_vault\_url) | Azure KeyVault URI for the Demo Container |
164+
| <a name="output_oidc_issuer_url"></a> [oidc\_issuer\_url](#output\_oidc\_issuer\_url) | AKS Cluster OIDC Issuer URL |
167165
| <a name="output_resource_group"></a> [resource\_group](#output\_resource\_group) | Resource group name |
168166
| <a name="output_tenant_id"></a> [tenant\_id](#output\_tenant\_id) | Azure tenant ID |
169167
| <a name="output_vault_name"></a> [vault\_name](#output\_vault\_name) | Vault name |

azure/iam.tf

-31
This file was deleted.

azure/identity.tf

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
############################################################################################################################
2+
## Here we need to create an Azure AD Application + a Service Principal and federate the application with the OIDC Issuer ##
3+
## so that Azure AD can exchange a token issued to the pod with a token that can be used to access other Azure resources. ##
4+
############################################################################################################################
5+
6+
7+
locals {
8+
namespace_name = "default"
9+
## This should match the name of the service account created by helm chart
10+
service_account_name = "wrongsecrets-sa"
11+
}
12+
13+
## Azure AD application that represents the app
14+
resource "azuread_application" "app" {
15+
display_name = "sp-wrongsecrets"
16+
}
17+
18+
resource "azuread_service_principal" "app" {
19+
client_id = azuread_application.app.client_id
20+
app_role_assignment_required = false
21+
}
22+
23+
resource "azuread_service_principal_password" "app" {
24+
service_principal_id = azuread_service_principal.app.id
25+
}
26+
27+
## Azure AD federated identity used to federate kubernetes with Azure AD
28+
resource "azuread_application_federated_identity_credential" "app" {
29+
application_id = azuread_application.app.application_id
30+
display_name = "fed-identity-app-wrongsecrets"
31+
description = "The federated identity used to federate K8s with Azure AD with the app service running in k8s wrongsecrets"
32+
audiences = ["api://AzureADTokenExchange"]
33+
issuer = azurerm_kubernetes_cluster.cluster.oidc_issuer_url
34+
subject = "system:serviceaccount:${local.namespace_name}:${local.service_account_name}"
35+
}

azure/k8s-vault-azure-start.sh

+11-15
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ export CLUSTER_NAME="$(terraform output -raw cluster_name)"
2121
export IDENTITY_RESOURCE_GROUP="$(az aks show -g ${RESOURCE_GROUP} -n ${CLUSTER_NAME} --query nodeResourceGroup -otsv)"
2222
export IDENTITY_NAME="wrongsecrets-identity"
2323

24-
export AZ_POD_RESOURCE_ID="$(terraform output -raw aad_pod_identity_resource_id)"
25-
export AZ_POD_CLIENT_ID="$(terraform output -raw aad_pod_identity_client_id)"
26-
27-
export AZ_EXTRA_POD_RESOURCE_ID="$(terraform output -raw aad_extra_pod_identity_resource_id)"
28-
export AZ_EXTRA_POD_CLIENT_ID="$(terraform output -raw aad_extra_pod_identity_client_id)"
24+
export AZ_AD_APP_CLIENT_ID="$(terraform output -raw app_client_id)"
2925

3026
export AZ_VAULT_URI="$(terraform output -raw vault_uri)"
3127
export AZ_KEY_VAULT_TENANT_ID="$(terraform output -raw tenant_id)"
@@ -67,19 +63,19 @@ else
6763
helm install csi csi-secrets-store-provider-azure/csi-secrets-store-provider-azure --namespace kube-system
6864
fi
6965

70-
#TO BE REPLACED WITH https://azure.github.io/azure-workload-identity/docs/installation.html
71-
echo "Add Azure pod identity to repo"
72-
helm repo add aad-pod-identity https://raw.githubusercontent.com/Azure/aad-pod-identity/master/charts
66+
echo "Add Azure workload identity to repo"
67+
helm repo add azure-workload-identity https://azure.github.io/azure-workload-identity/charts
7368

74-
helm list --namespace kube-system | grep 'aad-pod-identity' &>/dev/null
69+
helm list --namespace kube-system | grep 'workload-identity-webhook' &>/dev/null
7570
if [ $? == 0 ]; then
76-
echo "Azure pod identity chart already installed"
71+
echo "Azure workload identity chart already installed"
7772
else
78-
helm upgrade --install aad-pod-identity aad-pod-identity/aad-pod-identity #NO LONGER WORKS BECAUSE OF OUR CONFIUGRATION (RESTRICTED IN DEFAULT)
73+
helm install workload-identity-webhook azure-workload-identity/workload-identity-webhook \
74+
--namespace azure-workload-identity-system \
75+
--create-namespace \
76+
--set azureTenantID="${AZURE_TENANT_ID}"
7977
fi
8078

81-
#END TO BE REPLACED WITH https://azure.github.io/azure-workload-identity/docs/installation.html
82-
8379
echo "Generate secret manager challenge secret 2"
8480
az keyvault secret set --name wrongsecret-2 --vault-name "${AZ_KEY_VAULT_NAME}" --value "$(openssl rand -base64 16)" >/dev/null
8581

@@ -92,10 +88,10 @@ envsubst <./k8s/secret-volume.yml.tpl >./k8s/secret-volume.yml
9288
echo "Apply secretsmanager storage volume"
9389
kubectl apply -f./k8s/secret-volume.yml
9490

95-
envsubst <./k8s/pod-id.yml.tpl >./k8s/pod-id.yml
91+
envsubst <./k8s/serviceAccount.yml.tpl >./k8s/serviceAccount.yml
9692
envsubst <./k8s/secret-challenge-vault-deployment.yml.tpl >./k8s/secret-challenge-vault-deployment.yml
9793

98-
kubectl apply -f./k8s/pod-id.yml
94+
kubectl apply -f./k8s/serviceAccount.yml
9995

10096
while [[ $(kubectl --namespace=default get pods -l "app.kubernetes.io/component=mic" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True True" ]]; do echo "waiting for component=mic" && sleep 2; done
10197
while [[ $(kubectl --namespace=default get pods -l "app.kubernetes.io/component=nmi" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do echo "waiting for component=nmi" && sleep 2; done

azure/k8s/pod-id.yml.tpl

-33
This file was deleted.

azure/k8s/secret-challenge-vault-deployment.yml.tpl

+1-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ kind: Deployment
33
metadata:
44
labels:
55
app: secret-challenge
6-
aadpodidbinding: wrongsecrets-pod-id
76
name: secret-challenge
87
namespace: default
98
spec:
@@ -20,17 +19,15 @@ spec:
2019
type: RollingUpdate
2120
template:
2221
metadata:
23-
creationTimestamp: "2020-10-28T20:21:04Z"
2422
labels:
2523
app: secret-challenge
26-
aadpodidbinding: wrongsecrets-pod-id
2724
name: secret-challenge
2825
spec:
2926
securityContext:
3027
runAsUser: 2000
3128
runAsGroup: 2000
3229
fsGroup: 2000
33-
serviceAccountName: vault
30+
serviceAccountName: wrongsecrets-sa
3431
volumes:
3532
- name: 'ephemeral'
3633
emptyDir: {}
@@ -92,8 +89,6 @@ spec:
9289
value: wrongsecret-3
9390
- name: SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTYSOURCES_0_ENDPOINT
9491
value: ${AZ_VAULT_URI}
95-
- name: SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTYSOURCES_0_CREDENTIAL_CLIENTID
96-
value: ${AZ_POD_CLIENT_ID}
9792
- name: SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTYSOURCES_0_CREDENTIAL_MANAGEDIDENTITYENABLED
9893
value: "true"
9994
- name: SPECIAL_K8S_SECRET

azure/k8s/secret-volume.yml.tpl

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ metadata:
55
spec:
66
provider: azure
77
parameters:
8-
usePodIdentity: "true"
98
tenantId: ${AZ_KEY_VAULT_TENANT_ID}
109
keyvaultName: ${AZ_KEY_VAULT_NAME}
1110
objects: |

azure/k8s/serviceAccount.yaml.tpl

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: v1
2+
kind: ServiceAccount
3+
metadata:
4+
name: wrongsecrets-sa
5+
labels:
6+
azure.workload.identity/use: "true" # Represents the service account is to be used for workload identity, see https://azure.github.io/azure-workload-identity/docs/topics/service-account-labels-and-annotations.html
7+
annotations:
8+
azure.workload.identity/client-id: ${AZ_AD_APP_CLIENT_ID}
9+
azure.workload.identity/tenant-id: ${AZURE_TENANT_ID}
10+
azure.workload.identity/service-account-token-expiration: "86400" # Token is valid for 1 day

azure/main.tf

+4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ resource "azurerm_kubernetes_cluster" "cluster" {
5151

5252
kubernetes_version = var.cluster_version
5353

54+
oidc_issuer_enabled = true
55+
56+
workload_identity_enabled = true
57+
5458
api_server_access_profile {
5559
authorized_ip_ranges = ["${data.http.ip.response_body}/32"]
5660
}

azure/outputs.tf

+8-18
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,19 @@ output "cluster_name" {
88
description = "AKS Cluster name"
99
}
1010

11-
output "resource_group" {
12-
value = azurerm_kubernetes_cluster.cluster.resource_group_name
13-
description = "Resource group name"
11+
output "oidc_issuer_url" {
12+
value = azurerm_kubernetes_cluster.cluster.oidc_issuer_url
13+
description = "AKS Cluster OIDC Issuer URL"
1414
}
1515

16-
output "aad_pod_identity_resource_id" {
17-
value = azurerm_user_assigned_identity.aks_pod_identity.id
18-
description = "Resource ID for the Managed Identity for AAD Pod Identity"
19-
}
2016

21-
output "aad_pod_identity_client_id" {
22-
value = azurerm_user_assigned_identity.aks_pod_identity.client_id
23-
description = "Client ID for the Managed Identity for AAD Pod Identity"
17+
output "app_client_id" {
18+
value = azuread_application.app.application_id
2419
}
2520

26-
output "aad_extra_pod_identity_resource_id" {
27-
value = azurerm_user_assigned_identity.aks_extra_pod_identity.id
28-
description = "Resource ID for the Managed Identity for AAD Pod Identity"
29-
}
30-
31-
output "aad_extra_pod_identity_client_id" {
32-
value = azurerm_user_assigned_identity.aks_extra_pod_identity.client_id
33-
description = "Client ID for the Managed Identity for AAD Pod Identity"
21+
output "resource_group" {
22+
value = azurerm_kubernetes_cluster.cluster.resource_group_name
23+
description = "Resource group name"
3424
}
3525

3626
output "vault_uri" {

azure/secrets.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ resource "azurerm_key_vault_access_policy" "user" {
3939
resource "azurerm_key_vault_access_policy" "identity_access" {
4040
key_vault_id = azurerm_key_vault.vault.id
4141
tenant_id = data.azurerm_client_config.current.tenant_id
42-
object_id = azurerm_user_assigned_identity.aks_pod_identity.principal_id
42+
object_id = azuread_service_principal.app.id
4343

4444
secret_permissions = [
4545
"Get", "List"
@@ -107,7 +107,7 @@ resource "azurerm_key_vault_secret" "wrongsecret_3" {
107107
resource "azurerm_key_vault_access_policy" "extra_identity_access" {
108108
key_vault_id = azurerm_key_vault.vault.id
109109
tenant_id = data.azurerm_client_config.current.tenant_id
110-
object_id = azurerm_user_assigned_identity.aks_extra_pod_identity.principal_id
110+
object_id = azuread_service_principal.app.id
111111

112112
secret_permissions = [
113113
"Get", "List"

azure/versions.tf

+4
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@ terraform {
1414
source = "hashicorp/http"
1515
version = "~> 3.4.0"
1616
}
17+
azuread = {
18+
source = "hashicorp/azuread"
19+
version = "2.47.0"
20+
}
1721
}
1822
}

0 commit comments

Comments
 (0)