Skip to content

Commit 90fcd8a

Browse files
author
Benjamin P. Jung
committed
Enable the possibility to target EKS clusters.
This enables the use of IAM roles for service accounts. Closes #3
1 parent 690e6b8 commit 90fcd8a

File tree

5 files changed

+83
-10
lines changed

5 files changed

+83
-10
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/.terraform/
22
*.tfstate*
3+
*.auto.tfvars

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
[3.0.0] - 2020-01-22
99

10+
## Added
11+
12+
- The type of the Kubernetes cluster can no be specified.
13+
Set this to `eks` if targeting a managed [EKS](https://aws.amazon.com/eks/) Cluster.
14+
- If targeting EKS clusters, pods will use IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)
15+
as intended by AWS.
16+
1017
## Updated
1118

1219
- The default version of the controller has been set to [v1.1.5](https://github.com/kubernetes-sigs/aws-alb-ingress-controller/releases/tag/v1.1.5)

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,13 @@
22

33
This Terraform module can be used to install the [AWS ALB Ingress Controller](https://github.com/kubernetes-sigs/aws-alb-ingress-controller)
44
into a Kubernetes cluster.
5+
6+
## Improved integration with Amazon Elastic Kubernetes Service (EKS)
7+
8+
This module can be used to install the ALB Ingress controller into a "vanilla" Kubernetes cluster (which is the default)
9+
or it can be used to integrate tightly with AWS-managed [EKS](https://aws.amazon.com/eks/) clusters which allows the deployed pods to
10+
[use IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html).
11+
12+
It is required, that an OpenID connect provider [has already been created](https://www.terraform.io/docs/providers/aws/r/eks_cluster.html#example-iam-role-for-eks-cluster) for your EKS cluster for this feature to work.
13+
14+
Just make sure that you set the variable `k8s_cluster_type` type if running on EKS.

main.tf

+54-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
locals {
22
aws_alb_ingress_controller_docker_image = "docker.io/amazon/aws-alb-ingress-controller:v${var.aws_alb_ingress_controller_version}"
3+
aws_alb_ingress_controller_version = var.aws_alb_ingress_controller_version
34
aws_alb_ingress_class = "alb"
5+
aws_vpc_id = data.aws_vpc.selected.id
6+
aws_region_name = data.aws_region.current.name
7+
}
8+
9+
data "aws_vpc" "selected" {
10+
id = var.k8s_cluster_type == "eks" ? data.aws_eks_cluster.selected[0].vpc_config[0].vpc_id : var.aws_vpc_id
11+
}
12+
13+
data "aws_region" "current" {
14+
name = var.aws_region_name
15+
}
16+
17+
data "aws_caller_identity" "current" {}
18+
19+
# The EKS cluster (if any) that represents the installation target.
20+
data "aws_eks_cluster" "selected" {
21+
count = var.k8s_cluster_type == "eks" ? 1 : 0
22+
name = var.k8s_cluster_name
423
}
524

625
data "aws_iam_policy_document" "ec2_assume_role" {
26+
count = var.k8s_cluster_type == "vanilla" ? 1 : 0
727
statement {
828
actions = ["sts:AssumeRole"]
929

@@ -14,6 +34,27 @@ data "aws_iam_policy_document" "ec2_assume_role" {
1434
}
1535
}
1636

37+
data "aws_iam_policy_document" "eks_oidc_assume_role" {
38+
count = var.k8s_cluster_type == "eks" ? 1 : 0
39+
statement {
40+
actions = ["sts:AssumeRoleWithWebIdentity"]
41+
effect = "Allow"
42+
condition {
43+
test = "StringEquals"
44+
variable = "${replace(data.aws_eks_cluster.selected[0].identity[0].oidc[0].issuer, "https://", "")}:sub"
45+
values = [
46+
"system:serviceaccount:${var.k8s_namespace}:aws-alb-ingress-controller"
47+
]
48+
}
49+
principals {
50+
identifiers = [
51+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${replace(data.aws_eks_cluster.selected[0].identity[0].oidc[0].issuer, "https://", "")}"
52+
]
53+
type = "Federated"
54+
}
55+
}
56+
}
57+
1758
resource "aws_iam_role" "this" {
1859
name = "${var.aws_resource_name_prefix}${var.k8s_cluster_name}-alb-ingress-controller"
1960
description = "Permissions required by the Kubernetes AWS ALB Ingress controller to do it's job."
@@ -23,7 +64,7 @@ resource "aws_iam_role" "this" {
2364

2465
force_detach_policies = true
2566

26-
assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json
67+
assume_role_policy = var.k8s_cluster_type == "vanilla" ? data.aws_iam_policy_document.ec2_assume_role[0].json : data.aws_iam_policy_document.eks_oidc_assume_role[0].json
2768
}
2869

2970
data "aws_iam_policy_document" "alb_management" {
@@ -144,7 +185,7 @@ data "aws_iam_policy_document" "alb_management" {
144185

145186
resource "aws_iam_policy" "this" {
146187
name = "${var.aws_resource_name_prefix}${var.k8s_cluster_name}-alb-management"
147-
description = "Permissions that are required to manage the AWS Application Load Balancer."
188+
description = "Permissions that are required to manage AWS Application Load Balancers."
148189
path = var.aws_iam_path_prefix
149190
policy = data.aws_iam_policy_document.alb_management.json
150191
}
@@ -159,7 +200,11 @@ resource "kubernetes_service_account" "this" {
159200
metadata {
160201
name = "aws-alb-ingress-controller"
161202
namespace = var.k8s_namespace
162-
203+
annotations = {
204+
# This annotation is only used when running on EKS which can
205+
# use IAM roles for service accounts.
206+
"eks.amazonaws.com/role-arn" = aws_iam_role.this.arn
207+
}
163208
labels = {
164209
"app.kubernetes.io/name" = "aws-alb-ingress-controller"
165210
"app.kubernetes.io/managed-by" = "terraform"
@@ -257,7 +302,7 @@ resource "kubernetes_deployment" "this" {
257302

258303
labels = {
259304
"app.kubernetes.io/name" = "aws-alb-ingress-controller"
260-
"app.kubernetes.io/version" = local.aws_alb_ingress_controller_version
305+
"app.kubernetes.io/version" = "v${local.aws_alb_ingress_controller_version}"
261306
"app.kubernetes.io/managed-by" = "terraform"
262307
}
263308

@@ -281,9 +326,10 @@ resource "kubernetes_deployment" "this" {
281326
"app.kubernetes.io/name" = "aws-alb-ingress-controller"
282327
"app.kubernetes.io/version" = local.aws_alb_ingress_controller_version
283328
}
284-
285329
annotations = {
286-
# Annotation to be used by KIAM
330+
# Annotation which is only used by KIAM and kube2iam.
331+
# Should be ignored by your cluster if using IAM roles for service accounts, e.g.
332+
# when running on EKS.
287333
"iam.amazonaws.com/role" = aws_iam_role.this.arn
288334
}
289335
}
@@ -301,8 +347,8 @@ resource "kubernetes_deployment" "this" {
301347
args = [
302348
"--ingress-class=${local.aws_alb_ingress_class}",
303349
"--cluster-name=${var.k8s_cluster_name}",
304-
"--aws-vpc-id=${var.aws_vpc_id}",
305-
"--aws-region=${var.aws_region_name}",
350+
"--aws-vpc-id=${local.aws_vpc_id}",
351+
"--aws-region=${local.aws_region_name}",
306352
"--aws-max-retries=10",
307353
]
308354

variables.tf

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
variable "k8s_cluster_type" {
2+
description = "Can be set to `vanilla` or `eks`. If set to `eks`, the Kubernetes cluster will be assumed to be run on EKS which will make sure that the AWS IAM Service integration works as supposed to."
3+
type = string
4+
default = "vanilla"
5+
}
6+
17
variable "k8s_cluster_name" {
28
description = "Name of the Kubernetes cluster. This string is used to contruct the AWS IAM permissions and roles."
39
type = string
@@ -11,14 +17,17 @@ variable "k8s_namespace" {
1117
variable "aws_iam_path_prefix" {
1218
description = "Prefix to be used for all AWS IAM objects."
1319
type = string
20+
default = ""
1421
}
1522

1623
variable "aws_vpc_id" {
17-
type = string
24+
type = string
25+
default = null
1826
}
1927

2028
variable "aws_region_name" {
21-
type = string
29+
type = string
30+
default = null
2231
}
2332

2433
variable "aws_resource_name_prefix" {

0 commit comments

Comments
 (0)