How-To: Configure Azure AD as an OIDC Identity Provider for EKS

Steve Wade
6 min readSep 16, 2021

--

Problem statement

The problem statement for this piece of work was as follows:

As a platform engineer
I want our to provide other engineers with EKS access securely
So that we can easily audit usage and simplify off-boarding

Glossary

Before we go any further I think its important to have a glossary of terms to aid understanding, so here we go …

  • OIDC — OpenID Connect, for more information see here.
  • Azure AD — Azure Active Directory, for more information see here.
  • aad — An abbreviation for Azure Active Directory.

Implementation

The following section lists the steps required to implement this configuration, the order is important!

1. Azure configuration

We firstly need to configure the Azure side of the house, this is honestly where the majority of the configuration happens and the order of these steps is extremely important.

1.1 Enterprise Application to be used as the OIDC identity provider

  1. Login to Azure AD portal as user that has sufficient permission to create Azure AD application and manage permission and select Azure Active Directory from Azure Services.
  2. From the sidebar click on Enterprise Application
  3. From the top click on New Application> Create your own application

This will open a wizard to create an Azure AD Application, provide a name for your application and click create.

1.2 Registered Application (#1)
Secondly, we now need to configure the application registration that is automatically created when we created the Enterprise Application above.

Navigate back to Azure Active Directory

From the sidebar click on “App registrations”

Select the name of the application you configured in part 1.1

Click authentication on the left hand sub navigation menu

Under Redirect URIs simply add http://localhost (see below)

Make sure ID tokens is checked (see below)

Make sure Allow public client flows is set to yes (see below)

Click Save

From the sidecar click on “Token configuration”

From the top click on “Add group claims”

Make sure the following are selected

From the sidecar click on “API permissions”

Click on “Add new permission”

Click on “APIs my organization uses”

Search for AWS-EKS-SSO and add the permission, you should now see your Enterprise application added (see example below).

From the sidecar click on “Certificates & secrets”

Click on “New client secret”

Name the secret AWS-EKS-SSO give it an expiry of 24 months.

🚨Make a note of the secret value, we are going to need it later 🚨

1.3 Registered Application (#2)
Finally, we need to configure a brand new application to act as our client when interacting with kubectl .

Login to Azure AD portal as user that has sufficient permission to create Azure AD application and manage permission and select Azure Active Directory from Azure Services.

From the sidebar click on App registrations

From the top click on New registration

Give it a name of AWS-EKS-KUBECTL

Click authentication on the left hand sub navigation menu

Under Redirect URIs simply add http://localhost (see below)

Make sure ID tokens is checked (see below)

Make sure Allow public client flows is set to yes (see below)

Click Save

2. EKS configuration (via Terraform)

I am used to leveraging Terraform to configure AWS infrastructure to the steps below detail the Terraform configuration required to implement OIDC on our EKS cluster.

variable "oidc_configuration" {
description = "The configuration for the OIDC provider."
type = object({
client_id = string
groups_claim = string
groups_prefix = string
issuer_url = string
provider = string
username_claim = string
username_prefix = string
})
default = {
client_id = "XXX-XXX-XXX-XXX-XXX" # AWS-EKS-SSO app id
groups_claim = "groups"
groups_prefix = "aad:"
issuer_url = "https://sts.windows.net/<tenant_id>/"
provider = "AzureAD"
username_claim = "upn"
username_prefix = "aad:"
}
}

The client_id above is the application ID of our AWS-EKS-SSO registered application configured as part of our Azure setup above.

The tenant_id above is your organisations tenant ID within Azure, see Directory (tenant) id on either of the registered applications configured as part of our Azure setup above.

The / at the end of issuer_url is extremely important it needs to be there!

We now need to add the identity provider resource (see below)

resource "aws_eks_identity_provider_config" "eks_identity_provider" {
cluster_name = aws_eks_cluster.eks.name

oidc {
client_id = var.oidc_configuration["client_id"]
groups_claim = var.oidc_configuration["groups_claim"]
groups_prefix = var.oidc_configuration["groups_prefix"]
identity_provider_config_name = var.oidc_configuration["provider"]
issuer_url = var.oidc_configuration["issuer_url"]
username_claim = var.oidc_configuration["username_claim"]
username_prefix = var.oidc_configuration["username_prefix"]
}

timeouts {
create = "2h"
delete = "2h"
}
}

The timeouts here were important because the defaults didn’t seem long enough for me to get the configuration to complete successfully.

3. ClusterRole/Role bindings

We now need to add ClusterRoleBindings or RoleBindings to the cluster so that once we authenticate we have access to interact with the cluster, an example of this can be seen below.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sso-platform-engineering-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: aad:<group id> # aws-pe-admins group ID in Azure

The group name needs to be prefixed with aad: here to match the prefix we added as part of the EKS configuration in section 2 of this implementation.

I advise prefixing any ClusterRole/Role bindings with sso- to make it firstly bunch all bindings together when listing them as well as making it explicitly obvious you have to be using SSO to leverage these.

4. Configuring kubectl

In order to authenticate I used https://github.com/int128/kubelogin.

Firstly you need to install the plugin, I just krew and executed:

kubectl krew install oidc-login

Secondly, you need to authenticate using the following command:

kubectl oidc-login setup \
--oidc-issuer-url https://sts.windows.net/<tenant_id>/ \
--oidc-client-id YOUR_CLIENT_ID \
--oidc-client-secret YOUR_CLIENT_SECRET

Note: The secret is the value from section 1.2 of this blog post

The above command outputs your JWT token to validate you’ve successfully authenticated with Azure. Next you need to add the following to your kubeconfig file located at ~/.kube/config

users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://sts.windows.net/<tenant_id>/
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET

Note: The secret is the value from section 1.2 of this blog post

You can increase the log level by adding a -v1 argument above.

You should now be able to interact with EKS using the following …

kubectl --user=oidc <commands>

For example

kubectl --user=oidc get nodes

Summary

This blog post hopefully captures the steps required to configure Azure Active Directory as an OIDC identity provider to our EKS cluster(s).

Please feel free to add comments/suggestions for improving the kubectl configuration if you have them as this configuration is completely new to me. In the past I used Dex and Gangway to obtain a kubeconfig file.

--

--