Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 01f1aa8

Browse files
committedJun 18, 2025·
Max's edit
1 parent 849b977 commit 01f1aa8

4 files changed

+175
-125
lines changed
 

‎modules/distr-tracing-tempo-object-storage-setup-aws-sts-cco-install.adoc

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ include::snippets/technology-preview.adoc[leveloffset=+1]
2020

2121
. Create an AWS S3 bucket.
2222

23-
. Create the following `trust.json` file for the AWS IAM policy that will set up a trust relationship for the AWS IAM role, created in the next step, with the service account of the TempoStack instance:
23+
. Create the following `trust.json` file for the AWS Identity and Access Management (AWS IAM) policy for the purpose of setting up a trust relationship for the AWS IAM role, which is created in the next step, with the service account of the `TempoStack` instance:
2424
+
2525
[source,yaml]
2626
----
@@ -30,25 +30,33 @@ include::snippets/technology-preview.adoc[leveloffset=+1]
3030
{
3131
"Effect": "Allow",
3232
"Principal": {
33-
"Federated": "arn:aws:iam::${<aws_account_id>}:oidc-provider/${<oidc_provider>}" # <1>
33+
"Federated": "arn:aws:iam::<aws_account_id>:oidc-provider/<oidc_provider>" # <1>
3434
},
3535
"Action": "sts:AssumeRoleWithWebIdentity",
3636
"Condition": {
3737
"StringEquals": {
38-
"${OIDC_PROVIDER}:sub": [
39-
"system:serviceaccount:${<openshift_project_for_tempostack>}:tempo-${<tempostack_cr_name>}" # <2>
40-
"system:serviceaccount:${<openshift_project_for_tempostack>}:tempo-${<tempostack_cr_name>}-query-frontend"
38+
"<oidc_provider>:sub": [
39+
"system:serviceaccount:<openshift_project_for_tempostack>:tempo-<tempostack_cr_name>" # <2>
40+
"system:serviceaccount:<openshift_project_for_tempostack>:tempo-<tempostack_cr_name>-query-frontend"
4141
]
4242
}
4343
}
4444
}
4545
]
4646
}
4747
----
48-
<1> OIDC provider that you have configured on the {product-title}. You can get the configured OIDC provider value also by running the following command: `$ oc get authentication cluster -o json | jq -r '.spec.serviceAccountIssuer' | sed 's~http[s]*://~~g'`.
49-
<2> Namespace in which you intend to create the TempoStack instance.
48+
<1> The OIDC provider that you have configured on the {product-title}.
49+
<2> The namespace in which you intend to create the `TempoStack` instance.
50+
+
51+
[TIP]
52+
====
53+
You can also get the value for the configured OIDC provider by running the following command:
54+
----
55+
$ oc get authentication cluster -o json | jq -r '.spec.serviceAccountIssuer' | sed 's~http[s]*://~~g'
56+
----
57+
====
5058
51-
. Create an AWS IAM role by attaching the `trust.json` policy file that you created:
59+
. Create an AWS IAM role by attaching the created `trust.json` policy file:
5260
+
5361
[source,terminal]
5462
----
@@ -59,25 +67,25 @@ $ aws iam create-role \
5967
--output text
6068
----
6169
62-
. Attach an AWS IAM policy to the created role:
70+
. Attach an AWS IAM policy to the created AWS IAM role:
6371
+
6472
[source,terminal]
6573
----
6674
$ aws iam attach-role-policy \
6775
--role-name "tempo-s3-access" \
6876
--policy-arn "arn:aws:iam::aws:policy/AmazonS3FullAccess"
6977
----
70-
. Configure Cloud Provider environment for the tempo operator. In the case of AWS STS we need to add ROLEARN environment variable to the operator subcription.
78+
79+
. Configure the cloud provider environment for the {TempoOperator}:
7180
[source,terminal]
7281
----
73-
$ oc patch subscription <TEMPO_OPERATOR_SUB> \ <1>
74-
-n <TEMPO_OPERATOR_NAMESPACE> \ <2>
75-
--type='merge' -p '{"spec": {"config": {"env": [{"name": "ROLEARN", "value": "'"<ROLE_ARN>"'"}]}}}' <3>
76-
82+
$ oc patch subscription <tempo_operator_sub> \ # <1>
83+
-n <tempo_operator_namespace> \ # <2>
84+
--type='merge' -p '{"spec": {"config": {"env": [{"name": "ROLEARN", "value": "'"<role_arn>"'"}]}}}' # <3>
7785
----
7886
<1> Operator Subscription Name.
7987
<2> Namespace of the {TempoOperator}.
80-
<3> ARN of the role previously created.
88+
<3> The AWS STS requires adding the `ROLEARN` environment variable to the Operator subcription. As the `<ROLE_ARN>` value, add the Amazon Resource Name (ARN) of the AWS IAM role that you created in step 3.
8189
8290
. In the {product-title}, create an object storage secret with keys as follows:
8391
+
@@ -93,7 +101,8 @@ stringData:
93101
type: Opaque
94102
----
95103
96-
. When TempoStack CR is created you need to specify the credentialMode as follows:
104+
. When the is created you need to specify the credentialMode as follows:
105+
+
97106
[source,yaml]
98107
----
99108
apiVersion: tempo.grafana.com/v1alpha1
@@ -105,13 +114,14 @@ spec:
105114
storage:
106115
secret:
107116
name: aws-sts
108-
type: s3 <1>
109-
credentialMode: token-cco <2>
117+
type: s3 # <1>
118+
credentialMode: token-cco # <2>
110119
----
111-
<1> Currently this is the only backend supported togheter with CCO.
112-
<2> Credential mode should be set to token-cco.
113-
+
120+
<1> Currently, this is the only backend supported togheter with the CCO.
121+
<2> Must be set to the `token-cco` value.
122+
114123
. For tempo monolithic will be similar:
124+
+
115125
[source,yaml]
116126
----
117127
apiVersion: tempo.grafana.com/v1alpha1
@@ -122,10 +132,10 @@ metadata:
122132
spec:
123133
storage:
124134
traces:
125-
backend: s3 <1>
135+
backend: s3 # <1>
126136
s3:
127137
secret: aws-sts
128-
credentialMode: token-cco <2>
138+
credentialMode: token-cco # <2>
129139
----
130-
<1> Currently this is the only backend supported togheter with CCO.
131-
<2> Credential mode should be set to token-cco.
140+
<1> Currently, this is the only backend supported togheter with the CCO.
141+
<2> Must be set to the `token-cco` value.

‎modules/distr-tracing-tempo-object-storage-setup-azure-sts-install.adoc

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,97 +3,124 @@
33
//* observability/distr_tracing/distr-tracing-tempo-installing.adoc
44

55
:_mod-docs-content-type: PROCEDURE
6-
[id="distr-tracing-tempo-object-storage-setup-azure-sts-install_{context}"]
6+
[id="setting-up-azure-storage-with-security-token-service_{context}"]
77
= Setting up the Azure storage with the Security Token Service
88

9-
You can set up Azure storage with the Security Token Service (STS) by using the Azure Command Line Interface (AZ CLI).
9+
You can set up the Azure storage with the Security Token Service (STS) by using the Azure Command Line Interface (Azure CLI).
1010

1111
:FeatureName: Azure storage with the Security Token Service
1212
include::snippets/technology-preview.adoc[leveloffset=+1]
1313

1414
.Prerequisites
1515

16-
* You have installed the latest version of the AWS CLI.
17-
* Created an Azure Storage Account.
18-
* Created an Azure Blob Storage Container.
16+
* You have installed the latest version of the Azure CLI.
17+
* You have created an Azure storage account.
18+
* You have created an Azure blob storage container.
1919
2020
.Procedure
21-
. Create an Azure Managed identity
21+
22+
. Create an Azure managed identity:
23+
+
2224
[source,terminal]
2325
----
24-
az identity create \
25-
--name <IDENTITY_NAME> \ <1>
26-
--resource-group <RESOURCE_GROUP> \ <2>
27-
--location <REGION> \ <3>
28-
--subscription <SUBSCRIPTION_ID> <4>
26+
$ az identity create \
27+
--name <identity_name> \ # <1>
28+
--resource-group <resource_group> \ # <2>
29+
--location <region> \ # <3>
30+
--subscription <subscription_id> # <4>
2931
----
30-
<1> Name of the identity to be created.
31-
<2> The Azure resource group where the identity will be created.
32-
<3> The Azure region; it should be the same region as the resource group.
32+
<1> Choose a name for the managed identity.
33+
<2> The Azure resource group where the identity is to be created.
34+
<3> The Azure region, which must be the same region as for the resource group.
3335
<4> Azure subscription ID.
36+
37+
. Create a federated identity credential for the Kubernetes service account for use by all components except the frontend component:
3438
+
35-
. Create federated credentials. Federated credentials allow Kubernetes service accounts to authenticate as the Azure managed identity without storing secrets or using service principals. You need to create one per Kubernetes service account. In this case, the operator will create one service account for all components and one specific for the frontend component.
3639
[source,terminal]
3740
----
38-
az identity federated-credential create \
39-
--name <CREDENTIAL_NAME> \ <1>
40-
--identity-name <IDENTITY_NAME> \
41-
--resource-group <RESOURCE_GROUP> \
42-
--issuer <CLUSTER_ISSUER> \ <2>
43-
--subject <TEMPO_SA_SUBJECT> \ <3>
44-
--audiences <AUDIENCE> <4>
45-
----
46-
<1> Name of the federated credential.
47-
<2> The OIDC issuer URL of the Kubernetes cluster. You can get it using the following command: `oc get authentication cluster -o json | jq -r .spec.serviceAccountIssuer`
48-
<3> The Kubernetes service account subject, in the format: `system:serviceaccount:<namespace>:tempo-<tempo-instance-name>`
49-
<4> The expected audience used to validate tokens, commonly set to `api://AzureADTokenExchange`.
41+
$ az identity federated-credential create \ # <1>
42+
--name <credential_name> \ # <2>
43+
--identity-name <identity_name> \
44+
--resource-group <resource_group> \
45+
--issuer <cluster_issuer> \ # <3>
46+
--subject <tempo_sa_subject> \ # <4>
47+
--audiences <audience> # <5>
48+
----
49+
<1> Federated identity credentials allow Kubernetes service accounts to authenticate as an Azure managed identity without storing secrets or using an Azure service principal identity.
50+
<2> Choose a name for the federated credential.
51+
<3> The URL of the OpenID Connect (OIDC) issuer for your cluster.
52+
<4> The service account subject for your cluster in the following format: `system:serviceaccount:<namespace>:tempo-<tempostack_instance_name>`.
53+
<5> The expected audience, which is to be used for validating the issued tokens for the federated identity credential. This is commonly set to `api://AzureADTokenExchange`.
54+
+
55+
[TIP]
56+
====
57+
You can get the URL of the OpenID Connect (OIDC) issuer for your cluster by running the following command:
58+
----
59+
$ oc get authentication cluster -o json | jq -r .spec.serviceAccountIssuer
60+
----
61+
====
62+
63+
. Create a federated identity credential for the Kubernetes service account for use by the frontend component:
5064
+
51-
Create frontend federated credential.
5265
[source,terminal]
5366
----
54-
az identity federated-credential create \
55-
--name <CREDENTIAL_NAME>-frontend \ <1>
56-
--identity-name <IDENTITY_NAME> \
57-
--resource-group <RESOURCE_GROUP> \
58-
--issuer <CLUSTER_ISSUER> \
59-
--subject <TEMPO_SA_QUERY_FRONTEND_SUBJECT> \ <2>
60-
--audiences <AUDIENCE> | jq
67+
$ az identity federated-credential create \ # <1>
68+
--name <credential_name>-frontend \ # <2>
69+
--identity-name <identity_name> \
70+
--resource-group <resource_group> \
71+
--issuer <cluster_issuer> \
72+
--subject <tempo_sa_query_frontend_subject> \ # <3>
73+
--audiences <audience> | jq
6174
----
62-
<1> Name of the federated credential.
63-
<2> The Kubernetes service account subject, in the format: `system:serviceaccount:<namespace>:tempo-<tempo-instance-name>`
75+
<1> Federated identity credentials allow Kubernetes service accounts to authenticate as an Azure managed identity without storing secrets or using an Azure service principal identity.
76+
<2> Choose a name for the frontend federated identity credential.
77+
<3> The service account subject for your cluster in the following format: `system:serviceaccount:<namespace>:tempo-<tempostack_instance_name>`.
78+
79+
. Assign the Storage Blob Data Contributor role to the Azure service principal identity of your created Azure managed identity:
6480
+
65-
. Assign the "Storage Blob Data Contributor" role to the managed identity's service principal.
6681
[source,terminal]
6782
----
68-
az role assignment create \
69-
--assignee <ASSIGNEE_NAME> \ <1>
83+
$ az role assignment create \
84+
--assignee <assignee_name> \ # <1>
7085
--role "Storage Blob Data Contributor" \
71-
--scope "/subscriptions/<SUBSCRIPTION_ID>
86+
--scope "/subscriptions/<subscription_id>
7287
----
73-
<1> Managed identity principal. Can be obtained with the following command: `az ad sp list --all --filter "servicePrincipalType eq 'ManagedIdentity'" | jq -r --arg idName <IDENTITY_NAME> '.[] | select(.displayName == $idName) | .appId'`
88+
<1> The Azure service principal identity of the Azure managed identity that you created in step 1.
7489
+
75-
. Fetch the client ID of the existing managed identity.
76-
[source,terminal]
90+
[TIP]
91+
====
92+
You can get the `<assignee_name>` value by running the following command:
93+
----
94+
$ az ad sp list --all --filter "servicePrincipalType eq 'ManagedIdentity'" | jq -r --arg idName <identity_name> '.[] | select(.displayName == $idName) | .appId'`
95+
----
96+
====
97+
98+
. Fetch the client ID of the Azure managed identity that you created in step 1:
99+
+
100+
[source,bash]
77101
----
78102
CLIENT_ID=$(az identity show \
79-
--name <IDENTITY_NAME> \
80-
--resource-group <RESOURCE_GROUP> \
103+
--name <identity_name> \ # <1>
104+
--resource-group <resource_group> \ # <2>
81105
--query clientId \
82106
-o tsv)
83107
----
108+
<1> Copy and paste the `<identity_name>` value from step 1.
109+
<2> Copy and paste the `<resource_group>` value from step 1.
110+
111+
. Create a Kubernetes secret for the Azure workload identity federation (WIF):
84112
+
85-
. Create a Kubernetes secret for Azure WIF.
86113
[source,terminal]
87114
----
88-
kubectl create -n <TEMPO_NAMESPACE> secret generic azure-secret \
89-
--from-literal=container=<$AZURE_STORAGE_AZURE_CONTAINER> \ <1>
90-
--from-literal=account_name=<AZURE_STORAGE_AZURE_ACCOUNTNAME> \ <2>
91-
--from-literal=client_id=<CLIENT_ID> \ <3>
92-
--from-literal=audience=<AUDIENCE> \ <4>
93-
--from-literal=tenant_id=<TENANT_ID> <5>
94-
----
95-
<1> Azure Blob storage container.
96-
<2> Azure Storage account name.
97-
<3> Client ID of the managed identity (obtained in the previous step).
98-
<4> Audience, optional (defaults to `api://AzureADTokenExchange`).
99-
<5> Azure Tenant ID.
115+
$ kubectl create -n <tempo_namespace> secret generic azure-secret \
116+
--from-literal=container=<azure_storage_azure_container> \ # <1>
117+
--from-literal=account_name=<azure_storage_azure_accountname> \ # <2>
118+
--from-literal=client_id=<client_id> \ # <3>
119+
--from-literal=audience=<audience> \ # <4>
120+
--from-literal=tenant_id=<tenant_id> # <5>
121+
----
122+
<1> The name of the Azure Blob Storage container.
123+
<2> The name of the Azure Storage account.
124+
<3> The client ID of the managed identity that you fetched in the previous step.
125+
<4> Optional: Defaults to `api://AzureADTokenExchange`.
126+
<5> Azure Tenant ID.

‎modules/distr-tracing-tempo-object-storage-setup-gcp-sts-install.adoc

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,88 +17,91 @@ include::snippets/technology-preview.adoc[leveloffset=+1]
1717
1818
.Procedure
1919

20-
. Create a GCS bucket.
20+
. Create a GCS bucket on the Google Cloud Platform (GCP).
2121

2222
. Create or reuse a service account with Google's Identity and Access Management (IAM):
2323
+
24-
[source,terminal]
24+
[source,bash]
2525
----
26-
SERVICE_ACCOUNT_EMAIL=$(gcloud iam service-accounts create <IAM_SA_NAME> \ # <1>
26+
SERVICE_ACCOUNT_EMAIL=$(gcloud iam service-accounts create <iam_service_account_name> \ # <1>
2727
--display-name="Tempo Account" \
28-
--project <PROJECT_ID> \ # <2>
28+
--project <project_id> \ # <2>
2929
--format='value(email)' \
3030
--quiet)
3131
----
32-
<1> Name of the service account in Google Cloud.
33-
<2> Project ID of the service account in Google Cloud.
32+
<1> The name of the service account on the GCP.
33+
<2> The project ID of the service account on the GCP.
3434

35-
. Bind the required GCP roles to the created SA at the project level:
35+
. Bind the required GCP roles to the created service account at the project level:
3636
+
3737
[source,terminal]
3838
----
39-
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
39+
$ gcloud projects add-iam-policy-binding <project_id> \
4040
--member "serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
41-
--role="roles/iam.workloadIdentityUser"
42-
43-
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
41+
--role="roles/iam.workloadIdentityUser" \
42+
&&
43+
gcloud projects add-iam-policy-binding <project_id> \
4444
--member "serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
4545
--role "roles/storage.objectAdmin"
46-
4746
----
48-
. Retrieve the `POOL_ID` of the Google Cloud Workload Identity Pool associated with the OpenShift cluster.
47+
48+
. Retrieve the `POOL_ID` value of the Google Cloud Workload Identity Pool that is associated with the cluster:
4949
+
5050
[source,terminal]
5151
----
52-
$ OIDC_ISSUER=$(oc get authentication.config cluster -o jsonpath='{.spec.serviceAccountIssuer}')
53-
54-
$ POOL_ID=$(echo "$OIDC_ISSUER" | awk -F'/' '{print $NF}' | sed 's/-oidc$//')
52+
$ OIDC_ISSUER=$(oc get authentication.config cluster -o jsonpath='{.spec.serviceAccountIssuer}') \
53+
&&
54+
POOL_ID=$(echo "$OIDC_ISSUER" | awk -F'/' '{print $NF}' | sed 's/-oidc$//')
5555
----
56-
. Allow Kubernetes Service Accounts to impersonate the Google Service Account, SERVICE_ACCOUNT_EMAIL is the output of the commant used to created the service account in the step 2.
56+
57+
. Permit the Kubernetes Service Accounts to impersonate the Google Service Account:
5758
+
5859
[source,terminal]
5960
----
60-
$ gcloud iam service-accounts add-iam-policy-binding "$SERVICE_ACCOUNT_EMAIL" \
61+
$ gcloud iam service-accounts add-iam-policy-binding "$SERVICE_ACCOUNT_EMAIL" \ # <1>
6162
--role="roles/iam.workloadIdentityUser" \
62-
--member="principal://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/<POOL_ID>/subject/system:serviceaccount:<TEMPO_NAMESPACE>:tempo-<TEMPO_NAME>" \
63-
--project=<PROJECT_ID> \
64-
--quiet
65-
66-
$ gcloud iam service-accounts add-iam-policy-binding "$SERVICE_ACCOUNT_EMAIL" \
63+
--member="principal://iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/<pool_id>/subject/system:serviceaccount:<tempo_namespace>:tempo-<tempo_name>" \
64+
--project=<project_id> \
65+
--quiet \
66+
&&
67+
gcloud iam service-accounts add-iam-policy-binding "$SERVICE_ACCOUNT_EMAIL" \
6768
--role="roles/iam.workloadIdentityUser" \
68-
--member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/subject/system:serviceaccount:${TEMPO_NAMESPACE}:tempo-${TEMPO_NAME}-query-frontend" \
69-
--project="$PROJECT_ID" \
69+
--member="principal://iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/<pool_id>/subject/system:serviceaccount:<tempo_namespace>:tempo-<tempo_name>-query-frontend" \
70+
--project=<project_id> \
7071
--quiet
7172
----
72-
. Create credential file used by Tempo Stack, this will be in the key.json key in the storage secret:
73+
<1> The `$SERVICE_ACCOUNT_EMAIL` is the output of the command in step 2.
74+
75+
. Create a credential file for the `key.json` key of the storage secret for use by the `TempoStack` custom resource:
7376
+
7477
[source,terminal]
7578
----
7679
$ gcloud iam workload-identity-pools create-cred-config \
77-
"projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/$POOL_ID/providers/<PROVIDER_ID>" \
80+
"projects/<project_number>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>" \
7881
--service-account="$SERVICE_ACCOUNT_EMAIL" \
79-
--credential-source-file=/var/run/secrets/storage/serviceaccount/token \
82+
--credential-source-file=/var/run/secrets/storage/serviceaccount/token \ # <1>
8083
--credential-source-type=text \
81-
--output-file=<OUTPUT_FILE_PATH> #<1>
84+
--output-file=<output_file_path> # <2>
8285
----
83-
<1> Path where the file will be writed
84-
+
85-
Note: credential-source-file should be always point to /var/run/secrets/storage/serviceaccount/token, this is where the operator will mount the token
86+
<1> The `credential-source-file` parameter must always point to the `/var/run/secrets/storage/serviceaccount/token` path because the Operator mounts the token from this path.
87+
<2> The path for saving the output file.
88+
8689
. Get the correct audience as follows:
8790
+
8891
[source,terminal]
8992
----
9093
gcloud iam workload-identity-pools providers describe "$PROVIDER_NAME" --format='value(oidc.allowedAudiences[0])'
9194
----
92-
+
93-
. Create storage secret to be used by Tempo.
95+
96+
. Create a storage secret for the {TempoShortName}.
9497
+
9598
[source,terminal]
9699
----
97-
kubectl -n <TEMPO_NAMESPACE> create secret generic gcs-secret \
98-
--from-literal=bucketname="<BUCKET_NAME> \ #<1>
99-
--from-literal=audience="<AUDIENCE> \ #<2>
100-
--from-file=key.json=<OUTPUT_FILE_PATH> #<3>
100+
kubectl -n <tempo_namespace> create secret generic gcs-secret \
101+
--from-literal=bucketname="<bucket_name> \ # <1>
102+
--from-literal=audience="<audience> \ # <2>
103+
--from-file=key.json=<output_file_path> # <3>
101104
----
102-
<1> Bucket name of the Google Cloud Storage
103-
<2> Audience we get in the previous step
104-
<3> This is the file we created with gcloud iam workload-identity-pools create-cred-config command.
105+
<1> The bucket name of the Google Cloud Storage.
106+
<2> The audience that you got in the previous step.
107+
<3> The credential file that you created in step 6.

‎observability/distr_tracing/distr-tracing-tempo-installing.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,18 @@ include::modules/distr-tracing-tempo-storage-ref.adoc[leveloffset=+1]
3838

3939
include::modules/distr-tracing-tempo-object-storage-setup-aws-sts-install.adoc[leveloffset=+2]
4040

41+
[role="_additional-resources"]
42+
.Additional resources
43+
44+
* link:https://docs.aws.amazon.com/cli/[AWS Command Line Interface Documentation] (AWS Documentation)
45+
4146
include::modules/distr-tracing-tempo-object-storage-setup-azure-sts-install.adoc[leveloffset=+2]
4247

48+
[role="_additional-resources"]
49+
.Additional resources
50+
51+
* link:https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux[Install the Azure CLI on Linux] (Azure documentation)
52+
4353
include::modules/distr-tracing-tempo-object-storage-setup-gcp-sts-install.adoc[leveloffset=+2]
4454

4555
[role="_additional-resources"]

0 commit comments

Comments
 (0)
Please sign in to comment.