Skip to content

Commit

Permalink
Clean up Azure AD Workload ID docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mboersma committed May 1, 2024
1 parent d817ab3 commit ca91421
Showing 1 changed file with 134 additions and 135 deletions.
269 changes: 134 additions & 135 deletions docs/book/src/topics/workload-identity.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,86 @@
# Workload Identity

Azure AD Workload identity is the next iteration of Azure AD Pod identity
that enables Kubernetes applications (e.g. CAPZ) to access Azure cloud
Azure AD Workload identity is the next iteration of Azure AD Pod identity
that enables Kubernetes applications such as CAPZ to access Azure cloud
resources securely with Azure Active Directory.

This document describes a quick start guide of using workload identity and
assumes that you have access to Azure cloud.
Let's help you get started using workload identity. We assume
you have access to Azure cloud services.

Workload identity is currently worked upon and cloud provider azure
integration is in progress. Please refer to [this](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues/3589) issue for details.
For more information, please refer to the [proposal](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/docs/proposals/20221611-workload-identity-integration.md)
## Quick start

## Workload Identity Quick Start Guide
### Set up a management cluster with kind

### Setting Up Management Cluster on Kind
- Create a private and public key pair. For example, using OpenSSL:

- Create a public and private key pair. For example, you can generate the
key pairs using OpenSSL.
```bash
openssl genrsa -out sa.key 2048
openssl rsa -in sa.key -pubout -out sa.pub
```

Generate a private key called `sa.key` using the following command:
```bash
$ openssl genrsa -out sa.key 2048
```
Set the environment variable `SERVICE_ACCOUNT_SIGNING_KEY_FILE` to the full path
of the `sa.key` private key file you just generated, and set `SERVICE_ACCOUNT_KEY_FILE`
to the generated `sa.pub` public key file.

Set the environment variable `SERVICE_ACCOUNT_SIGNING_KEY_FILE` to the path of the
generated `sa.key`. This ENV var will be used in the upcoming step.
Note: You can use `readlink -f sa.key` to get the absolute path of the key file.
```bash
export SERVICE_ACCOUNT_SIGNING_KEY_FILE=$(realpath sa.key)
export SERVICE_ACCOUNT_KEY_FILE=$(realpath sa.pub)
```

Generate a public key using the private key.
```bash
$ openssl rsa -in sa.key -pubout -out sa.pub
```
Set the environment variable `SERVICE_ACCOUNT_KEY_FILE` to the path of the
generated `sa.pub`. This ENV var will be used in the upcoming step.

- Create and upload Discovery and JWKS document using this [link](https://azure.github.io/azure-workload-identity/docs/installation/self-managed-clusters/oidc-issuer.html)

- At this stage, you will need to create TWO federated identity credentials: one for CAPZ and one for ASO.
- You can create those either with Azure AD application or user-assigned
identity. Please note that user assigned identity will need to be created
regardless because cloud provider azure integration is not yet done. The
steps are mentioned in the next section of workload cluster creation.
- The next list items links to steps on creating the federated
identity credentials. You will need to set up several environment
variables for each one:
- `SERVICE_ACCOUNT_NAMESPACE` : Namespace where the capz-manager and
azureserviceoperator-controller-manager pods will run.
- `SERVICE_ACCOUNT_NAME` : Name of the capz-manager or azureserviceoperator-default k8s service account.
- `SERVICE_ACCOUNT_ISSUER` : This is the path of the Azure storage
container which you created in the previous step which is:
`"https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/"`

- Create federated identity credentials for each of CAPZ and ASO using the steps outlined [here](https://azure.github.io/azure-workload-identity/docs/topics/federated-identity-credential.html)
You can either use `user-assigned-identity` or `AD application` to create federated identity credential and add `contributor` role to it.

- Create a Kind cluster with necessary flags with the following command:
These environment variables will be used later, when creating the kind cluster.

```bash
cat <<EOF | kind create cluster --name azure-workload-identity --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: ${SERVICE_ACCOUNT_KEY_FILE}
containerPath: /etc/kubernetes/pki/sa.pub
- hostPath: ${SERVICE_ACCOUNT_SIGNING_KEY_FILE}
containerPath: /etc/kubernetes/pki/sa.key
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
apiServer:
extraArgs:
service-account-issuer: ${SERVICE_ACCOUNT_ISSUER}
service-account-key-file: /etc/kubernetes/pki/sa.pub
service-account-signing-key-file: /etc/kubernetes/pki/sa.key
controllerManager:
extraArgs:
service-account-private-key-file: /etc/kubernetes/pki/sa.key
EOF
```
- Create and upload a discovery document

- Initialize a management cluster using `clusterctl` using the below command.
If you do not have `clusterctl` installed, then follow this [link](https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl)
to install.
```bash
$ clusterctl init --infrastructure azure
```
Create and upload a JWKS discovery document by following [these instructions](https://azure.github.io/azure-workload-identity/docs/installation/self-managed-clusters/oidc-issuer.html).

- Create two federated identity credentials

Export environment variables used for creating a federated identity credential:

- `SERVICE_ACCOUNT_NAMESPACE`: Namespace where the capz-manager and
azureserviceoperator-controller-manager pods will run. Default is `capz-system`.
- `SERVICE_ACCOUNT_NAME`: Name of the capz-manager or azureserviceoperator-default k8s service account. Default is `capz-manager` for CAPZ and `azureserviceoperator-default` for ASO.
- `SERVICE_ACCOUNT_ISSUER`: Path of the Azure storage container created in the previous step, specifically:
- `"https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/"`

Create two federated identity credentials, one for CAPZ and one for ASO, by following [these instructions](https://azure.github.io/azure-workload-identity/docs/topics/federated-identity-credential.html). You'll need to set `SERVICE_ACCOUNT_NAME` and `SERVICE_ACCOUNT_NAMESPACE` to different values for each credential.
Use either `user-assigned-identity` or `AD application` when creating the credentials, and add the `contributor` role to each.
- Create a kind cluster with the following command:
```bash
cat <<EOF | kind create cluster --name azure-workload-identity --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: ${SERVICE_ACCOUNT_KEY_FILE}
containerPath: /etc/kubernetes/pki/sa.pub
- hostPath: ${SERVICE_ACCOUNT_SIGNING_KEY_FILE}
containerPath: /etc/kubernetes/pki/sa.key
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
apiServer:
extraArgs:
service-account-issuer: ${SERVICE_ACCOUNT_ISSUER}
service-account-key-file: /etc/kubernetes/pki/sa.pub
service-account-signing-key-file: /etc/kubernetes/pki/sa.key
controllerManager:
extraArgs:
service-account-private-key-file: /etc/kubernetes/pki/sa.key
EOF
```
- Initialize the kind cluster as a CAPZ management cluster using `clusterctl`:
```bash
clusterctl init --infrastructure azure
```
If you don't have `clusterctl` installed, follow [these instructions](https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl)
to install it.

### Creating a Workload Cluster

Expand All @@ -96,76 +90,81 @@ a user-assigned managed identity in Azure. Save its name which will be used late
- [Create a role assignment](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal-managed-identity)
to give the identity Contributor access to the Azure subscription where the workload cluster will be created.

- Before generating a workload cluster YAML configuration set the
- Before generating a workload cluster YAML configuration, set the
following environment variables.
```bash
export AZURE_SUBSCRIPTION_ID=<your-azure-subscription-id>
# This is the client ID of the AAD app or user-assigned identity that you used to created the federated identity.
export AZURE_CLIENT_ID=<your-azure-client-id>
export AZURE_TENANT_ID=<your-azure-tenant-id>
export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_B2s"
export AZURE_NODE_MACHINE_TYPE="Standard_B2s"
export AZURE_LOCATION="eastus"

# Identity secret. Though these are not used in workload identity, we still
# need to set them for the sake of generating the workload cluster YAML configuration
export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret"
export CLUSTER_IDENTITY_NAME="cluster-identity"
export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default"
```

```bash
export AZURE_SUBSCRIPTION_ID=<your-azure-subscription-id>
# This is the client ID of the AAD app or user-assigned identity that you used to created the federated identity.
export AZURE_CLIENT_ID=<your-azure-client-id>
export AZURE_TENANT_ID=<your-azure-tenant-id>
export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_B2s"
export AZURE_NODE_MACHINE_TYPE="Standard_B2s"
export AZURE_LOCATION="eastus"
# Identity secret. Though these are not used in workload identity, we still
# need to set them for the sake of generating the workload cluster YAML configuration
export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret"
export CLUSTER_IDENTITY_NAME="cluster-identity"
export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default"
```

- Generate a workload cluster template using the following command.

```bash
clusterctl generate cluster azwi-quickstart --kubernetes-version v1.27.3 --worker-machine-count=3 > azwi-quickstart.yaml
```
```bash
clusterctl generate cluster azwi-quickstart --kubernetes-version v1.27.3 --worker-machine-count=3 > azwi-quickstart.yaml
```

- Edit the generated `azwi-quickstart.yaml` to make the following changes for
workload identity to the `AzureClusterIdentity` object.
workload identity to the `AzureClusterIdentity` object:

- Change the type to `WorkloadIdentity`.
- Remove the `clientSecret` spec.

The AzureClusterIdentity specification should look like the following.
```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureClusterIdentity
metadata:
name: cluster-identity
spec:
type: WorkloadIdentity
allowedNamespaces:
list:
- <cluster-namespace>
tenantID: <your-tenant-id>
clientID: <your-client-id>
```
The AzureClusterIdentity specification should look like the following.
```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureClusterIdentity
metadata:
name: cluster-identity
spec:
type: WorkloadIdentity
allowedNamespaces:
list:
- <cluster-namespace>
tenantID: <your-tenant-id>
clientID: <your-client-id>
```

- Change the `AzureMachineTemplate` for both control plane and worker to include user-assigned-identity by
adding the following in its `spec`.
```yaml
identity: UserAssigned
userAssignedIdentities:
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME}
```
A sample `AzureMahineTemplate` after the edit should look like the below:

```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureMachineTemplate
metadata:
name: ${CLUSTER_NAME}-md-0
namespace: default
spec:
template:
spec:
osDisk:
diskSizeGB: 128
osType: Linux
sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""}
identity: UserAssigned
userAssignedIdentities:
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME}
vmSize: ${AZURE_NODE_MACHINE_TYPE}
```

```yaml
identity: UserAssigned
userAssignedIdentities:
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME}
```

A sample `AzureMachineTemplate` after the edit should look like the below:

```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AzureMachineTemplate
metadata:
name: ${CLUSTER_NAME}-md-0
namespace: default
spec:
template:
spec:
osDisk:
diskSizeGB: 128
osType: Linux
sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""}
identity: UserAssigned
userAssignedIdentities:
- providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME}
vmSize: ${AZURE_NODE_MACHINE_TYPE}
```

- At this stage, you can apply this yaml to create a workload cluster.

Expand Down

0 comments on commit ca91421

Please sign in to comment.