feat!: Add support for Outposts, remove node security group, add support for addon preserve and most_recent configurations (#2250)

Co-authored-by: Anton Babenko <anton@antonbabenko.com>
Resolves undefined
This commit is contained in:
Bryant Biggs
2022-12-05 16:26:23 -05:00
committed by GitHub
parent efbe952632
commit b2e97ca3dc
66 changed files with 2749 additions and 1776 deletions

152
main.tf
View File

@@ -1,11 +1,13 @@
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}
data "aws_default_tags" "current" {}
locals {
create = var.create && var.putin_khuylo
cluster_role = try(aws_iam_role.this[0].arn, var.iam_role_arn)
create_outposts_local_cluster = length(var.outpost_config) > 0
enable_cluster_encryption_config = length(var.cluster_encryption_config) > 0 && !local.create_outposts_local_cluster
}
################################################################################
@@ -25,16 +27,32 @@ resource "aws_eks_cluster" "this" {
subnet_ids = coalescelist(var.control_plane_subnet_ids, var.subnet_ids)
endpoint_private_access = var.cluster_endpoint_private_access
endpoint_public_access = var.cluster_endpoint_public_access
public_access_cidrs = var.cluster_endpoint_public_access_cidrs
public_access_cidrs = var.cluster_endpoint_public_access ? var.cluster_endpoint_public_access_cidrs : []
}
kubernetes_network_config {
ip_family = var.cluster_ip_family
service_ipv4_cidr = var.cluster_service_ipv4_cidr
dynamic "kubernetes_network_config" {
# Not valid on Outposts
for_each = local.create_outposts_local_cluster ? [] : [1]
content {
ip_family = var.cluster_ip_family
service_ipv4_cidr = var.cluster_service_ipv4_cidr
service_ipv6_cidr = var.cluster_service_ipv6_cidr
}
}
dynamic "outpost_config" {
for_each = local.create_outposts_local_cluster ? [var.outpost_config] : []
content {
control_plane_instance_type = outpost_config.value.control_plane_instance_type
outpost_arns = outpost_config.value.outpost_arns
}
}
dynamic "encryption_config" {
for_each = toset(var.cluster_encryption_config)
# Not available on Outposts
for_each = local.enable_cluster_encryption_config ? [var.cluster_encryption_config] : []
content {
provider {
@@ -67,9 +85,8 @@ resource "aws_ec2_tag" "cluster_primary_security_group" {
# This should not affect the name of the cluster primary security group
# Ref: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2006
# Ref: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2008
# `aws_default_tags` is merged in to "dedupe" tags and stabilize tag updates
for_each = { for k, v in merge(var.tags, var.cluster_tags, data.aws_default_tags.current.tags) :
k => v if local.create && k != "Name" && var.create_cluster_primary_security_group_tags
for_each = { for k, v in merge(var.tags, var.cluster_tags) :
k => v if local.create && k != "Name" && var.create_cluster_primary_security_group_tags && v != null
}
resource_id = aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id
@@ -93,9 +110,9 @@ resource "aws_cloudwatch_log_group" "this" {
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "1.0.2" # Note - be mindful of Terraform/provider version compatibility between modules
version = "1.1.0" # Note - be mindful of Terraform/provider version compatibility between modules
create = local.create && var.create_kms_key
create = local.create && var.create_kms_key && !local.create_outposts_local_cluster # not valid on Outposts
description = coalesce(var.kms_key_description, "${var.cluster_name} cluster encryption key")
key_usage = "ENCRYPT_DECRYPT"
@@ -129,7 +146,7 @@ locals {
cluster_security_group_id = local.create_cluster_sg ? aws_security_group.cluster[0].id : var.cluster_security_group_id
# Do not add rules to node security group if the module is not creating it
cluster_security_group_rules = local.create_node_sg ? {
cluster_security_group_rules = { for k, v in {
ingress_nodes_443 = {
description = "Node groups to cluster API"
protocol = "tcp"
@@ -138,23 +155,7 @@ locals {
type = "ingress"
source_node_security_group = true
}
egress_nodes_443 = {
description = "Cluster API to node groups"
protocol = "tcp"
from_port = 443
to_port = 443
type = "egress"
source_node_security_group = true
}
egress_nodes_kubelet = {
description = "Cluster API to node kubelets"
protocol = "tcp"
from_port = 10250
to_port = 10250
type = "egress"
source_node_security_group = true
}
} : {}
} : k => v if local.create_node_sg }
}
resource "aws_security_group" "cluster" {
@@ -177,7 +178,10 @@ resource "aws_security_group" "cluster" {
}
resource "aws_security_group_rule" "cluster" {
for_each = { for k, v in merge(local.cluster_security_group_rules, var.cluster_security_group_additional_rules) : k => v if local.create_cluster_sg }
for_each = { for k, v in merge(
local.cluster_security_group_rules,
var.cluster_security_group_additional_rules
) : k => v if local.create_cluster_sg }
# Required
security_group_id = aws_security_group.cluster[0].id
@@ -187,15 +191,13 @@ resource "aws_security_group_rule" "cluster" {
type = each.value.type
# Optional
description = try(each.value.description, null)
cidr_blocks = try(each.value.cidr_blocks, null)
ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null)
prefix_list_ids = try(each.value.prefix_list_ids, [])
self = try(each.value.self, null)
source_security_group_id = try(
each.value.source_security_group_id,
try(each.value.source_node_security_group, false) ? local.node_security_group_id : null
)
description = lookup(each.value, "description", null)
cidr_blocks = lookup(each.value, "cidr_blocks", null)
ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null)
prefix_list_ids = lookup(each.value, "prefix_list_ids", [])
self = lookup(each.value, "self", null)
source_security_group_id = lookup(each.value, "source_security_group_id",
lookup(each.value, "source_node_security_group", false)) ? local.node_security_group_id : null
}
################################################################################
@@ -204,13 +206,15 @@ resource "aws_security_group_rule" "cluster" {
################################################################################
data "tls_certificate" "this" {
count = local.create && var.enable_irsa ? 1 : 0
# Not available on outposts
count = local.create && var.enable_irsa && !local.create_outposts_local_cluster ? 1 : 0
url = aws_eks_cluster.this[0].identity[0].oidc[0].issuer
}
resource "aws_iam_openid_connect_provider" "oidc_provider" {
count = local.create && var.enable_irsa ? 1 : 0
# Not available on outposts
count = local.create && var.enable_irsa && !local.create_outposts_local_cluster ? 1 : 0
client_id_list = distinct(compact(concat(["sts.${local.dns_suffix}"], var.openid_connect_audiences)))
thumbprint_list = concat(data.tls_certificate.this[0].certificates[*].sha1_fingerprint, var.custom_oidc_thumbprints)
@@ -227,9 +231,9 @@ resource "aws_iam_openid_connect_provider" "oidc_provider" {
################################################################################
locals {
create_iam_role = local.create && var.create_iam_role
iam_role_name = coalesce(var.iam_role_name, "${var.cluster_name}-cluster")
policy_arn_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy"
create_iam_role = local.create && var.create_iam_role
iam_role_name = coalesce(var.iam_role_name, "${var.cluster_name}-cluster")
iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy"
cluster_encryption_policy_name = coalesce(var.cluster_encryption_policy_name, "${local.iam_role_name}-ClusterEncryption")
@@ -249,6 +253,17 @@ data "aws_iam_policy_document" "assume_role_policy" {
type = "Service"
identifiers = ["eks.${local.dns_suffix}"]
}
dynamic "principals" {
for_each = local.create_outposts_local_cluster ? [1] : []
content {
type = "Service"
identifiers = [
"ec2.${local.dns_suffix}",
]
}
}
}
}
@@ -292,10 +307,17 @@ resource "aws_iam_role" "this" {
# Policies attached ref https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html
resource "aws_iam_role_policy_attachment" "this" {
for_each = local.create_iam_role ? toset(compact(distinct(concat([
"${local.policy_arn_prefix}/AmazonEKSClusterPolicy",
"${local.policy_arn_prefix}/AmazonEKSVPCResourceController",
], var.iam_role_additional_policies)))) : toset([])
for_each = { for k, v in {
AmazonEKSClusterPolicy = local.create_outposts_local_cluster ? "${local.iam_role_policy_prefix}/AmazonEKSLocalOutpostClusterPolicy" : "${local.iam_role_policy_prefix}/AmazonEKSClusterPolicy",
AmazonEKSVPCResourceController = "${local.iam_role_policy_prefix}/AmazonEKSVPCResourceController",
} : k => v if local.create_iam_role }
policy_arn = each.value
role = aws_iam_role.this[0].name
}
resource "aws_iam_role_policy_attachment" "additional" {
for_each = { for k, v in var.iam_role_additional_policies : k => v if local.create_iam_role }
policy_arn = each.value
role = aws_iam_role.this[0].name
@@ -303,14 +325,16 @@ resource "aws_iam_role_policy_attachment" "this" {
# Using separate attachment due to `The "for_each" value depends on resource attributes that cannot be determined until apply`
resource "aws_iam_role_policy_attachment" "cluster_encryption" {
count = local.create_iam_role && var.attach_cluster_encryption_policy && length(var.cluster_encryption_config) > 0 ? 1 : 0
# Encryption config not available on Outposts
count = local.create_iam_role && var.attach_cluster_encryption_policy && local.enable_cluster_encryption_config ? 1 : 0
policy_arn = aws_iam_policy.cluster_encryption[0].arn
role = aws_iam_role.this[0].name
}
resource "aws_iam_policy" "cluster_encryption" {
count = local.create_iam_role && var.attach_cluster_encryption_policy && length(var.cluster_encryption_config) > 0 ? 1 : 0
# Encryption config not available on Outposts
count = local.create_iam_role && var.attach_cluster_encryption_policy && local.enable_cluster_encryption_config ? 1 : 0
name = var.cluster_encryption_policy_use_name_prefix ? null : local.cluster_encryption_policy_name
name_prefix = var.cluster_encryption_policy_use_name_prefix ? local.cluster_encryption_policy_name : null
@@ -328,7 +352,7 @@ resource "aws_iam_policy" "cluster_encryption" {
"kms:DescribeKey",
]
Effect = "Allow"
Resource = var.create_kms_key ? [module.kms.key_arn] : [for config in var.cluster_encryption_config : config.provider_key_arn]
Resource = var.create_kms_key ? module.kms.key_arn : var.cluster_encryption_config.provider_key_arn
},
]
})
@@ -341,14 +365,22 @@ resource "aws_iam_policy" "cluster_encryption" {
################################################################################
resource "aws_eks_addon" "this" {
for_each = { for k, v in var.cluster_addons : k => v if local.create }
# Not supported on outposts
for_each = { for k, v in var.cluster_addons : k => v if local.create && !local.create_outposts_local_cluster }
cluster_name = aws_eks_cluster.this[0].name
addon_name = try(each.value.name, each.key)
addon_version = lookup(each.value, "addon_version", null)
resolve_conflicts = lookup(each.value, "resolve_conflicts", null)
service_account_role_arn = lookup(each.value, "service_account_role_arn", null)
addon_version = try(each.value.addon_version, data.aws_eks_addon_version.this[each.key].version)
preserve = try(each.value.preserve, null)
resolve_conflicts = try(each.value.resolve_conflicts, "OVERWRITE")
service_account_role_arn = try(each.value.service_account_role_arn, null)
timeouts {
create = try(each.value.timeouts.create, var.cluster_addons_timeouts.create, null)
update = try(each.value.timeouts.update, var.cluster_addons_timeouts.update, null)
delete = try(each.value.timeouts.delete, var.cluster_addons_timeouts.delete, null)
}
depends_on = [
module.fargate_profile,
@@ -359,13 +391,21 @@ resource "aws_eks_addon" "this" {
tags = var.tags
}
data "aws_eks_addon_version" "this" {
for_each = { for k, v in var.cluster_addons : k => v if local.create && !local.create_outposts_local_cluster }
addon_name = try(each.value.name, each.key)
kubernetes_version = coalesce(var.cluster_version, aws_eks_cluster.this[0].version)
most_recent = try(each.value.most_recent, null)
}
################################################################################
# EKS Identity Provider
# Note - this is different from IRSA
################################################################################
resource "aws_eks_identity_provider_config" "this" {
for_each = { for k, v in var.cluster_identity_providers : k => v if local.create }
for_each = { for k, v in var.cluster_identity_providers : k => v if local.create && !local.create_outposts_local_cluster }
cluster_name = aws_eks_cluster.this[0].name