Skip to content

Commit

Permalink
Example module for configuring EKS for OIDC authentication (hashicorp…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexsomesan authored Sep 14, 2023
1 parent 6c38e7a commit 1b22349
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/2287.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:doc
Add example module for configuring OIDC authentication on EKS
```release-note:doc
10 changes: 9 additions & 1 deletion _examples/eks/eks-cluster/cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ resource "aws_eks_node_group" "k8s-acc" {

scaling_config {
desired_size = 1
max_size = 1
max_size = 3
min_size = 1
}

Expand All @@ -38,3 +38,11 @@ resource "aws_eks_node_group" "k8s-acc" {
aws_iam_role_policy_attachment.k8s-acc-AmazonEC2ContainerRegistryReadOnly,
]
}

output "cluster_url" {
value = aws_eks_cluster.k8s-acc.endpoint
}

output "cluster_ca" {
value = aws_eks_cluster.k8s-acc.certificate_authority[0].data
}
2 changes: 1 addition & 1 deletion _examples/eks/eks-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ variable "cluster_name" {

variable "kubernetes_version" {
type = string
default = "1.19"
default = "1.27"
}
2 changes: 1 addition & 1 deletion _examples/eks/eks-cluster/version.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.38.0"
version = "~> 5.0"
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions _examples/eks/eks-oidc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Configuring EKS for OIDC identity providers

Kubernetes, and by extension EKS, natively supports OIDC as an indentity provider to which it will delegate user authentication. The result of a successful authentication through OIDC is a base64 encoded token of data describing the user identity. The format of this token is called JWT (JSON Web Token) and is described by [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519).

The Kubernetes and Helm providers for Terraform are already designed to accept JWTs as indentity carriers. A token is passed to the provider by setting the `token` attribute on the provider block (or the `KUBE_TOKEN` environment variable).

Terraform Cloud can act as an OIDC identity provider to kubernetes, issuing JWT tokens that it designates as ["workload identity"](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/workload-identity-tokens). This module is designed around using TFC as an indentity provider, but will likely work with any OIDC compliant IDp, such as Okta.

# OIDC on EKS

EKS can be configured with an external IDp through the [`aws_eks_identity_provider_config`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_identity_provider_config) Terraform resource. This module is a thin wrapper around it, adding some meaningful defaults in the context of TFC (which can, of course be overridden) as well as the necessary RBAC role binding to grant permissions to the indentity obtained from OIDC.

To make use of the module, roughly follow the following steps (adapt for you actual needs):

1. Create an EKS cluster

Use the method of your choice to spin up an EKS cluster. One simple example is provided right here, in the sibling folder `eks-cluster`. Another way is making use of ["terraform-aws-modules/eks/aws"](https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest). Take note of the cluster's API endpoint URL as well as the cluster's API CA certificate. These will be needed later to configure the Kuberentes provider.

2. Apply this module

Make sure the same AWS credentials used for the above EKS cluster are avialable in the environment. Provide values for input variables as needed for your use case. For Terraform Cloud, reasonable defaults are baked into the module and all that's required is the name of the TFC Organization that will be used a the "admin group". Identities for all workloads in this org will be granted `cluster-admin` permission on the EKS cluster, via the group name extracted from the configured JWT claim (see input variables). To that end, this module creates a ClusterRoleBinding resource to bind the `cluster-admin` role with the user's group.

You are now ready to access your EKS cluster with indentity tokens provided by Terraform Cloud or your IDp of choice. The Kubernetes provider now only needs to be configured for [host endpoint](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#host) and [cluster CA](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#cluster_ca_certificate). In case you are running in Terraform Cloud, the token will automatically be injected into every run's environment (feature not rolled out yet). With other identity providers, you have to collect the token and supply it to the provider using the `KUBE_TOKEN` or the `token` provider attribute.
74 changes: 74 additions & 0 deletions _examples/eks/eks-oidc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "cluster_name" {
type = string
}

variable "oidc_issuer_url" {
default = "https://app.terraform.io"
}

variable "oidc_audience" {
default = "kubernetes"
}

variable "oidc_idp_name" {
default = "terraform-cloud"
}

variable "rbac_group_oidc_claim" {
default = "terraform_organization_name"
}

variable "rbac_admin_group_name" {
type = string
}

variable "rbac_group_cluster_role" {
default = "cluster-admin"
}

resource "aws_eks_identity_provider_config" "oidc_config" {
cluster_name = var.cluster_name

oidc {
identity_provider_config_name = var.oidc_idp_name
client_id = var.oidc_audience
issuer_url = var.oidc_issuer_url
username_claim = "sub"
groups_claim = var.rbac_group_oidc_claim
}
}

data "aws_eks_cluster" "target_eks" {
name = var.cluster_name
}

data "aws_eks_cluster_auth" "target_eks_auth" {
name = var.cluster_name
}

provider "kubernetes" {
host = data.aws_eks_cluster.target_eks.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.target_eks.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.target_eks_auth.token
}

resource "kubernetes_cluster_role_binding_v1" "oidc_role" {
metadata {
name = "odic-identity"
}

role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = var.rbac_group_cluster_role
}

subject {
api_group = "rbac.authorization.k8s.io"
kind = "Group"
name = var.rbac_admin_group_name
}
}

0 comments on commit 1b22349

Please sign in to comment.