Skip to content

Commit ead0426

Browse files
committed
Add documentation for Azure Workload Identity
1 parent 40c71b4 commit ead0426

5 files changed

Lines changed: 114 additions & 12 deletions

File tree

docs/configuration/azure-managed-prometheus.rst

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,49 @@ To configure Azure to send alerts to Robusta:
2020

2121
This notification is displayed until the first alert to Robusta.
2222

23-
Configure Robusta to use Azure managed Prometheus
23+
Configure Robusta to use Azure Managed Prometheus
2424
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2525

2626
For certain features, Robusta needs to reach out to Prometheus so that Robusta can analyze and present Prometheus data.
27-
In order to authenticate against the Azure managed Prometheus service, you have two options:
27+
Azure saves Prometheus metrics in an Azure Monitor Workspace. Robusta can access this data by using the Azure Monitor Workspace Query endpoint.
28+
29+
In order to authenticate against the Azure Monitor Workspace Query endpoint, you have multiple options:
30+
2831
- Create an Azure Active Directory authentication app (Option #1)
32+
2933
- Pros:
34+
3035
- Quick setup. Just need to create an app, get the credentials and add them to the manifests
3136
- Other pods can't use the Service Principal without having the secret
37+
3238
- Cons:
39+
3340
- Requires a service principal (Azure AD permission)
3441
- Need the client secret in the kubernetes manifests
3542
- Client secret expires, you need to manage its rotation
43+
3644
- Use Kubelet's Managed Identity (Option #2)
45+
3746
- Pros:
47+
3848
- Quick setup. Get the Managed Identity Client ID and add them to the manifests
3949
- No need to manage secrets. Removing the password element decreases the risk of the credentials being compromised
50+
4051
- Cons:
52+
4153
- Managed Identity is bound to the whole VMSS, so other pods can use it if they know the client ID
4254

55+
- Use Azure AD Workload Identity (Option #3)
56+
57+
- Pros:
58+
59+
- Most secure option as Managed Identity is only bound to the pod. No other pods can use it
60+
- No need to manage secrets. Removing the password element decreases the risk of the credentials being compromised
61+
62+
- Cons:
63+
64+
- Extra setup needed: need AKS cluster with Workload Identity add-on enabled, get the OIDC issuer URL and add it to the manifests
65+
4366
Get the Azure prometheus query endpoint
4467
=========================================
4568

@@ -59,7 +82,6 @@ Option #1: Create an Azure authentication app
5982
We will now create an Azure authentication app and get the necesssary credentials so Robusta can access Prometheus data.
6083

6184
1. Follow this Azure guide to `Register an app with Azure Active Directory <https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/prometheus-self-managed-grafana-azure-active-directory#register-an-app-with-azure-active-directory>`_
62-
6385
2. In your generated_values.yaml file add the following environment variables from the previous step.
6486

6587
.. code-block:: yaml
@@ -105,10 +127,64 @@ We will now use the Kubelet's Managed Identity so Robusta can access Prometheus
105127
106128
3. Give access to your Managed Identity on your workspace:
107129

108-
a. Open the Access Control (IAM) page for your Azure Monitor workspace in the Azure portal.
109-
b. Select Add role assignment.
110-
c. Select Monitoring Data Reader and select Next.
111-
d. For Assign access to, select Managed identity.
112-
e. Select + Select members.
113-
f. Select the Managed Identity you got from step 1
114-
g. Select Review + assign to save the configuration.
130+
#. Open the Access Control (IAM) page for your Azure Monitor workspace in the Azure portal.
131+
#. Select Add role assignment.
132+
#. Select Monitoring Data Reader and select Next.
133+
#. For Assign access to, select Managed identity.
134+
#. Select + Select members.
135+
#. Select the Managed Identity you got from step 1
136+
#. Select Review + assign to save the configuration.
137+
138+
Option #3: Use Azure Workload Identity
139+
==============================================
140+
141+
We will create a new Managed Identity and bound it to Robusta's Service Account so Robusta can access Prometheus data.
142+
143+
1. Requirements
144+
145+
AKS cluster needs to have Workload Identity add-on and OIDC issuer enabled. You can use `--enable-oidc-issuer --enable-workload-identity` with `az aks create` or `az aks update` to enable them.
146+
147+
2. Create a new Managed Identity. Change the Identity name, resource group and location to match your environment.
148+
149+
.. code-block:: bash
150+
151+
export SUBSCRIPTION="$(az account show --query id --output tsv)"
152+
az identity create --name "robusta-id" --resource-group "robusta-dev" --location "eastus" --subscription "${SUBSCRIPTION}"
153+
az identity show --name "robusta-id" --resource-group "robusta-dev" -query clientId -o tsv # keep this value for the step #3
154+
155+
3. In your generated_values.yaml file add the following environment variables from the previous step.
156+
157+
.. code-block:: yaml
158+
159+
runner:
160+
additional_env_vars:
161+
- name: PROMETHEUS_SSL_ENABLED
162+
value: "true"
163+
- name: AZURE_USE_WORKLOAD_ID
164+
value: "true"
165+
- name: AZURE_CLIENT_ID
166+
value: "<your-client-id>"
167+
- name: AZURE_TENANT_ID
168+
value: "<your-tenant-id>"
169+
azure:
170+
workloadIdentity:
171+
enabled: true
172+
173+
4. Federate the Service Account with the Managed Identity. Replace the values with the ones from the step #1.
174+
175+
.. code-block:: bash
176+
177+
export AKS_OIDC_ISSUER="$(az aks show -g <resource-group> -n <cluster-name> --query "oidcIssuerProfile.issuerUrl" -otsv)" # Replace with the corresponding values of your AKS clusters.
178+
ROBUSTA_NAMESPACE="robusta"
179+
ROBUSTA_SERVICE_ACCOUNT="robusta-runner-service-account"
180+
az identity federated-credential create --name "robusta-federated-id" --identity-name "robusta-id" --resource-group "robusta-dev" --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:$ROBUSTA_NAMESPACE:$ROBUSTA_SERVICE_ACCOUNT
181+
182+
5. Give access to your Managed Identity on your workspace:
183+
184+
#. Open the Access Control (IAM) page for your Azure Monitor workspace in the Azure portal.
185+
#. Select Add role assignment.
186+
#. Select Monitoring Data Reader and select Next.
187+
#. For Assign access to, select Managed identity.
188+
#. Select + Select members.
189+
#. Select the Managed Identity you got from step 2
190+
#. Select Review + assign to save the configuration.

helm/robusta/templates/runner-service-account.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ rules:
231231
apiVersion: v1
232232
kind: ServiceAccount
233233
metadata:
234+
{{- if .Values.azure.workloadIdentity.enabled }}
235+
annotations:
236+
azure.workload.identity/client-id: ${AZURE_CLIENT_ID}
237+
{{- end }}
234238
name: {{ .Release.Name }}-runner-service-account
235239
namespace: {{ .Release.Namespace }}
236240
---

helm/robusta/templates/runner.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ spec:
1515
labels:
1616
app: {{ .Release.Name }}-runner
1717
robustaComponent: "runner"
18+
{{- if .Values.azure.workloadIdentity.enabled }}
19+
annotations:
20+
azure.workload.identity/use: "true"
21+
{{- end }}
1822
{{- if .Values.runner.annotations }}
1923
annotations: {{ toYaml .Values.runner.annotations | nindent 8 }}
2024
{{- end }}

helm/robusta/values.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,8 @@ openshift:
560560

561561
sccPriority: null
562562
privilegedSccPriority: null
563+
564+
# custom parameters for Azure Managed Prometheus Service
565+
azure:
566+
workloadIdentity:
567+
enabled: false

src/robusta/integrations/prometheus/utils.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ def request_new_token(cls) -> bool:
6161
"resource": AZURE_RESOURCE,
6262
},
6363
)
64+
elif os.environ.get("AZURE_USE_WORKLOAD_ID"):
65+
token = open("/var/run/secrets/azure/tokens/azure-identity-token", "r").read()
66+
res = requests.post(
67+
url=AZURE_TOKEN_ENDPOINT,
68+
headers={"Content-Type": "application/x-www-form-urlencoded"},
69+
data={
70+
"grant_type": "client_credentials",
71+
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
72+
"client_assertion": token,
73+
"client_id": os.environ.get("AZURE_CLIENT_ID"),
74+
"scope": f"{AZURE_RESOURCE}/.default",
75+
},
76+
)
6477
else:
6578
res = requests.post(
6679
url=AZURE_TOKEN_ENDPOINT,
@@ -72,8 +85,8 @@ def request_new_token(cls) -> bool:
7285
"resource": AZURE_RESOURCE,
7386
},
7487
)
75-
except Exception:
76-
logging.exception("Unexpected error when trying to generate azure access token.")
88+
except Exception as e:
89+
logging.exception("Unexpected error when trying to generate azure access token: %s", e.message)
7790
return False
7891

7992
if not res.ok:

0 commit comments

Comments
 (0)