Simplifier l'accès aux services AWS pour les pods avec EKS Pod Identity

En novembre 2023, AWS a annoncé la sortie d’une nouvelle fonctionnalité pour faciliter la configuration des permissions IAM pour les pods hébergés sur Amazon Elastic Kubernetes Service EKS.
Avant cette annonce, j’avais toujours utilisé une autre méthode que j’implémente habituellement dans mes clusters EKS. IRSA pour IAM Role for Service Accounts.
Le principal avantage d’EKS Pod Identity est la simplicité qu’il apporte à l’automatisation de la gestion des droits que nous donnons aux applications dans les clusters EKS. Si vous êtes utilisateur de Terraform ou CloudFormation, je vous conseille de ne pas passer à côté de cette fonctionnalité, qui vous simplifiera la vie, croyez-moi. ;)
Mais avant de commencer avec EKS Pod Identity, faisons un petit retour en arrière.
Au début…
Un Service Account est un concept Kubernetes qui permet de donner une identité à un pod. Le problème est que le concept de Service Account n’existe pas sur AWS. Nous pensons en termes d’IAM Identities, tels que les utilisateurs ou les rôles.
Lorsque le service EKS a été lancé, si nous voulions donner à un pod la permission d’accéder à une ressource AWS, telle qu’un bucket S3, nous n’avions d’autre choix que d’assigner un rôle IAM au nœud (Instance EC2).
Et c’est à travers ce rôle que les pods obtenaient le droit d’interagir avec les services AWS. L’inconvénient majeur de cette méthode est que tous les pods déployés sur un nœud partagent les mêmes permissions.
Problématique lorsque vous essayez d’appliquer une stratégie de least privilege pour donner à chaque pod uniquement les permissions dont il a vraiment besoin…

2019, IRSA est lancé
Pour répondre à ce besoin de contrôle plus fin sur les permissions des pods, AWS lance IRSA (IAM Role for Service Accounts) en septembre 2019. Cette fonctionnalité introduit un mécanisme pour associer un Service Account à un rôle IAM. Mais pour en profiter, nous devons configurer quelques ressources :
- Un OIDC Provider, pour authentifier et autoriser un Service Account en utilisant le protocole OpenID connect
- Une role trust policy pour contrôler quel Service Account peut assumer un rôle IAM particulier.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated":
"arn:aws:iam::123456789012:oidc-provider/oidc.eks.eu-west-1.amazonaws.com
/id/<EKS_OIDC_PROVIDER_ID>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-1.amazonaws.com/id/<EKS_OIDC_PROVIDER_ID>:sub":
"system:serviceaccount:<NAMESPACE>:<SERVICE_ACCOUNT>"
}
}
}
]
}
- Un rôle IAM contenant les permissions habituelles pour accéder aux ressources AWS
- Un Service Account auquel une annotation spécifique doit être ajoutée pour référencer le rôle IAM auquel vous voulez l’associer
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-iam-role
L’inconvénient de cette fonctionnalité est que lorsque vous voulez automatiser la création d’un cluster avec IRSA, vous pouvez être confronté à un certain nombre de défis :
- Le fait que certains paramètres de configuration ne sont connus qu’une fois le cluster créé. Comme l’URL de l’OIDC provider dédiée au cluster, requise pour configurer le rôle IAM et le Service Account Kubernetes.
- Il doit y avoir un OIDC provider pour chaque cluster, ce qui peut causer des problèmes lorsque vous faites un déploiement Blue/Green, par exemple, et que vous voulez partager un rôle IAM pour des pods s’exécutant sur différents clusters. Dans ce cas, vous devez mettre à jour la Trust Policy pour autoriser l’OIDC provider pour le nouveau cluster.
- Certaines limitations peuvent être rencontrées, notamment sur la taille des Trust Policies, le nombre de rôles IAM ou le nombre maximum d’Identity Providers qui peuvent être créés sur un compte AWS.
- Lorsque vous devez créer de nouveaux clusters fréquemment, vous pouvez être ralenti par le fait que vous devez attendre plusieurs minutes pour que le cluster soit créé et prêt à être enregistré avec l’OIDC lors de sa création.

2023, EKS Pod Identity
AWS a pris en compte les retours des clients, et en novembre 2023 a lancé EKS Pod Identity.
Désormais, vous n’avez plus besoin de configurer un OIDC Provider ! Mais à la place un nouvel add-on Amazon EKS Pod Identity Agent qui peut être installé directement lors de la création d’un nouveau cluster.

Quant à la Trust Policy à définir pour un rôle IAM à assumer par un pod, il suffit de spécifier pods.eks.amazonaws.com comme service principal et de donner la permission d’ajouter des IAM Session Tags. Nous verrons pourquoi plus tard ;)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
Pour associer un Service Account à un rôle IAM, il ne reste plus qu’à créer un nouveau type de ressource appelé Pod Identity Association, que vous configurez en spécifiant le rôle IAM, le Service Account et le Namespace que vous voulez lier à votre pod.
Automatiser la création de toutes ces ressources rend la configuration beaucoup plus simple. Par exemple, voici un exemple de code Terraform pour installer un agent EKS Pod Identity, un rôle IAM et l’association entre rôle IAM et Service Account à la volée !
# Install EKS Pod Identity Agent on EKS Cluster
resource "aws_eks_addon" "example" {
cluster_name = "revolve"
addon_name = "eks-pod-identity-agent"
}
# Trust Policy for IAM Role
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["pods.eks.amazonaws.com"]
}
actions = [
"sts:AssumeRole",
"sts:TagSession"
]
}
}
# Policy that gives Read Only access to an S3 Bucket
data "aws_iam_policy_document" "pod_policy" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
]
resources = [
"s3://my-bucket/*",
]
}
}
# IAM Role and its associated policy.
resource "aws_iam_role" "pod_role" {
name = "S3ReadOnlyForPodsRole"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
policy = data.aws_iam_policy_document.pod_policy.json
}
# Here is where the magic happens!
# We map our IAM role to a pod by specifing its Cluster, Namespace and Service Account
resource "aws_eks_pod_identity_association" "example" {
cluster_name = "revolve"
namespace = "project"
service_account = "app"
role_arn = aws_iam_role.pod_role.arn
}
Plus tôt, nous parlions d’autoriser l’ajout d’IAM Session Tags à la Trust Policy. Une autre fonctionnalité ajoutée par EKS Pod Identity pour faciliter et contrôler la réutilisation d’un rôle pour des pods s’exécutant sur un cluster différent, un Namespace ou un Service Account différent est l’utilisation d’IAM Session Tags. Voici une liste de ceux qui sont automatiquement ajoutés par EKS Pod Identity aux credentials temporaires utilisés par un pod.
- eks-cluster-arn
- eks-cluster-name
- kubernetes-namespace
- kubernetes-service-account
- kubernetes-pod-name
- kubernetes-pod-uid
En revenant à notre exemple précédent, nous pouvons maintenant filtrer certaines actions de pod en fonction du cluster où il est déployé en ajoutant des conditions basées sur les Session Tags.

Dans cet exemple, nous définissons une policy qui autorise l’accès en lecture sur les objets S3 en fonction d’un eks-cluster-name Session Tag spécifique.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectTagging"
],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/eks-cluster-name": "${aws:PrincipalTag/eks-cluster-name}"
}
}
}
]
}
Si vous souhaitez en savoir plus sur le fonctionnement d’EKS Pod Identity, je recommande fortement de lire cette documentation officielle AWS ainsi que cet article écrit par les équipes de sécurité de Datadog.
Points clés à retenir
Pour conclure, EKS Pod Identity est une fonctionnalité qui simplifie la gestion des permissions pour les pods dans les clusters EKS, notamment pour les personnes comme moi qui sont habituées à automatiser le provisioning avec de l’IaC (Terraform). Le point clé ici est que vous n’avez plus besoin de configurer un OIDC Provider pour chaque cluster et les Trust Policies sont simplifiées.
L’association d’un Service Account avec un rôle IAM devient également beaucoup plus simple et facile.
Enfin, EKS Pod Identity nous permet de contrôler de manière sécurisée la réutilisation d’un rôle IAM pour les pods s’exécutant sur différents clusters, namespaces ou utilisant différents Service Accounts, grâce aux IAM Session Tags. Alors maintenant… êtes-vous convaincu de passer d’IRSA à EKS Pod Identity ? 🙂
Reyan's Cloudy Thoughts