diff --git a/README.md b/README.md index c723b3e253..4d63234066 100644 --- a/README.md +++ b/README.md @@ -173,8 +173,10 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a | cluster\_version | Kubernetes version to use for the EKS cluster. | `string` | `"1.16"` | no | | config\_output\_path | Where to save the Kubectl config file (if `write_kubeconfig = true`). Assumed to be a directory if the value ends with a forward slash `/`. | `string` | `"./"` | no | | create\_eks | Controls if EKS resources should be created (it affects almost all resources) | `bool` | `true` | no | +| create\_fargate\_pod\_execution\_role | Controls if the EKS Fargate pod execution IAM role should be created. | `bool` | `false` | no | | eks\_oidc\_root\_ca\_thumbprint | Thumbprint of Root CA for EKS OIDC, Valid until 2037 | `string` | `"9e99a48a9960b14926bb7f3b02e22da2b0ab7280"` | no | | enable\_irsa | Whether to create OpenID Connect Provider for EKS to enable IRSA | `bool` | `false` | no | +| fargate\_profiles | Fargate profiles |
map(object({
namespace = string
labels = map(string)
}))
| `{}` | no | | iam\_path | If provided, all IAM roles will be created on this path. | `string` | `"/"` | no | | kubeconfig\_aws\_authenticator\_additional\_args | Any additional arguments to pass to the authenticator such as the role to assume. e.g. ["-r", "MyEksRole"]. | `list(string)` | `[]` | no | | kubeconfig\_aws\_authenticator\_command | Command to use to fetch AWS EKS credentials. | `string` | `"aws-iam-authenticator"` | no | @@ -228,6 +230,8 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a | cluster\_security\_group\_id | Security group ID attached to the EKS cluster. On 1.14 or later, this is the 'Additional security groups' in the EKS console. | | cluster\_version | The Kubernetes server version for the EKS cluster. | | config\_map\_aws\_auth | A kubernetes configuration to authenticate to this EKS cluster. | +| fargate\_iam\_role\_arn | IAM role ARN for EKS Fargate pods | +| fargate\_iam\_role\_name | IAM role name for EKS Fargate pods | | kubeconfig | kubectl config file contents for this EKS cluster. | | kubeconfig\_filename | The filename of the generated kubectl config. | | node\_groups | Outputs from EKS node groups. Map of maps, keyed by var.node\_groups keys | diff --git a/aws_auth.tf b/aws_auth.tf index b583c069a9..7dc479421d 100644 --- a/aws_auth.tf +++ b/aws_auth.tf @@ -44,18 +44,20 @@ locals { local.auth_launch_template_worker_roles, local.auth_worker_roles, module.node_groups.aws_auth_roles, + module.fargate.aws_auth_roles, ) : { # Work around https://github.com/kubernetes-sigs/aws-iam-authenticator/issues/153 # Strip the leading slash off so that Terraform doesn't think it's a regex rolearn = replace(role["worker_role_arn"], replace(var.iam_path, "/^//", ""), "") - username = "system:node:{{EC2PrivateDNSName}}" + username = role["platform"] == "fargate" ? "system:node:{{SessionName}}" : "system:node:{{EC2PrivateDNSName}}" groups = tolist(concat( [ "system:bootstrappers", "system:nodes", ], - role["platform"] == "windows" ? ["eks:kube-proxy-windows"] : [] + role["platform"] == "windows" ? ["eks:kube-proxy-windows"] : [], + role["platform"] == "fargate" ? ["system:node-proxier"] : [], )) } ] diff --git a/fargate.tf b/fargate.tf new file mode 100644 index 0000000000..9734dfe51d --- /dev/null +++ b/fargate.tf @@ -0,0 +1,9 @@ +module "fargate" { + source = "./modules/fargate" + cluster_name = coalescelist(aws_eks_cluster.this[*].name, [""])[0] + create_eks = var.create_eks + create_fargate_pod_execution_role = var.create_fargate_pod_execution_role + fargate_profiles = var.fargate_profiles + subnets = var.subnets + tags = var.tags +} diff --git a/modules/fargate/fargate.tf b/modules/fargate/fargate.tf new file mode 100644 index 0000000000..d198dbfb05 --- /dev/null +++ b/modules/fargate/fargate.tf @@ -0,0 +1,44 @@ +# EKS Fargate Pod Execution Role + +data "aws_iam_policy_document" "eks_fargate_pod_assume_role" { + count = var.create_eks && var.create_fargate_pod_execution_role ? 1 : 0 + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["eks-fargate-pods.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "eks_fargate_pod" { + count = var.create_eks && var.create_fargate_pod_execution_role ? 1 : 0 + name = format("%s-fargate", var.cluster_name) + assume_role_policy = data.aws_iam_policy_document.eks_fargate_pod_assume_role[0].json + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "eks_fargate_pod" { + count = var.create_eks && var.create_fargate_pod_execution_role ? 1 : 0 + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy" + role = aws_iam_role.eks_fargate_pod[0].name +} + + +# EKS Fargate profiles + +resource "aws_eks_fargate_profile" "this" { + for_each = var.create_eks ? var.fargate_profiles : {} + cluster_name = var.cluster_name + fargate_profile_name = lookup(each.value, "name", format("%s-fargate-%s", var.cluster_name, replace(each.key, "_", "-"))) + pod_execution_role_arn = aws_iam_role.eks_fargate_pod[0].arn + subnet_ids = var.subnets + tags = var.tags + + selector { + namespace = each.value.namespace + labels = each.value.labels + } +} diff --git a/modules/fargate/outputs.tf b/modules/fargate/outputs.tf new file mode 100644 index 0000000000..5f5dff176a --- /dev/null +++ b/modules/fargate/outputs.tf @@ -0,0 +1,19 @@ +output "iam_role_name" { + description = "IAM role name for EKS Fargate pods" + value = element(concat(aws_iam_role.eks_fargate_pod.*.name, list("")), 0) +} + +output "iam_role_arn" { + description = "IAM role ARN for EKS Fargate pods" + value = element(concat(aws_iam_role.eks_fargate_pod.*.arn, list("")), 0) +} + +output "aws_auth_roles" { + description = "Roles for use in aws-auth ConfigMap" + value = [ + for role in aws_iam_role.eks_fargate_pod : { + worker_role_arn = role.arn + platform = "fargate" + } + ] +} diff --git a/modules/fargate/variables.tf b/modules/fargate/variables.tf new file mode 100644 index 0000000000..a2b055e01a --- /dev/null +++ b/modules/fargate/variables.tf @@ -0,0 +1,35 @@ +variable "cluster_name" { + description = "Name of parent cluster." + type = string +} + +variable "create_eks" { + description = "Controls if EKS resources should be created (it affects almost all resources)" + type = bool + default = true +} + +variable "create_fargate_pod_execution_role" { + description = "Controls if the EKS Fargate pod execution IAM role should be created." + type = bool + default = true +} + +variable "fargate_profiles" { + description = "Fargate profiles to create." + type = map(object({ + namespace = string + labels = map(string) + })) + default = {} +} + +variable "subnets" { + description = "A list of subnets for the EKS Fargate profiles." + type = list(string) +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) +} diff --git a/outputs.tf b/outputs.tf index b89ffcc9cb..322d88c40a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -161,6 +161,16 @@ output "worker_iam_role_arn" { )[0] } +output "fargate_iam_role_name" { + description = "IAM role name for EKS Fargate pods" + value = module.fargate.iam_role_name +} + +output "fargate_iam_role_arn" { + description = "IAM role ARN for EKS Fargate pods" + value = module.fargate.iam_role_arn +} + output "node_groups" { description = "Outputs from EKS node groups. Map of maps, keyed by var.node_groups keys" value = module.node_groups.node_groups diff --git a/variables.tf b/variables.tf index 460bdc687f..6a59161c2b 100644 --- a/variables.tf +++ b/variables.tf @@ -338,3 +338,18 @@ variable "cluster_encryption_config" { })) default = [] } + +variable "fargate_profiles" { + description = "Fargate profiles" + type = map(object({ + namespace = string + labels = map(string) + })) + default = {} +} + +variable "create_fargate_pod_execution_role" { + description = "Controls if the EKS Fargate pod execution IAM role should be created." + type = bool + default = false +}