Kubernetes IAM roles
The following Terraform file creates an IAM role for a Kubernetes ServiceAccount to use so that a workload resource is able to assume that IAM role via the ServiceAccount
variable "cluster_oidc_issuers" {
description = "List of ODIC issuers of clusters which the application will be deployed into, this is needed for allowing the IAM role to be assumed by the cluster's workload resources"
type = list(object({
id = string,
k8s_namespace = string,
k8s_service_account = string,
region = string,
}))
}
locals {
name_k8s = "iam_role_name"
}
data "aws_caller_identity" "current" {}
# ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role
resource "aws_iam_role" "k8s" {
name = local.name_k8s
assume_role_policy = data.aws_iam_policy_document.allow_eks_to_assume_role.json
inline_policy {
name = local.name_k8s
policy = data.aws_iam_policy_document.main.json
}
}
# ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document
data "aws_iam_policy_document" "allow_eks_to_assume_role" {
dynamic "statement" {
for_each = toset(var.cluster_oidc_issuers)
content {
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/oidc.eks.${statement.value.region}.amazonaws.com/id/${statement.value.id}"
]
}
condition {
test = "StringEquals"
variable = "oidc.eks.${statement.value.region}.amazonaws.com/id/${statement.value.id}:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "oidc.eks.${statement.value.region}.amazonaws.com/id/${statement.value.id}:sub"
values = [
"system:serviceaccount:${statement.value.k8s_namespace}:${statement.value.k8s_service_account}",
]
}
}
}
}
# ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document
data "aws_iam_policy_document" "main" {
statement {
sid = "Placeholder"
actions = [
"sts:GetCallerIdentity",
]
resources = [
"*"
]
}
}
output "iam_role_k8s" {
description = "Details of the IAM role to bind to the application's ServiceAccount resource"
value = {
arn = aws_iam_role.k8s.arn,
assume_role_policy = jsondecode(aws_iam_role.k8s.assume_role_policy),
inline_policy = [for inline_policy in aws_iam_role.k8s.inline_policy : jsondecode(inline_policy.policy)],
name = aws_iam_role.k8s.name,
}
}
Last updated