mirror of
https://github.com/ysoftdevs/terraform-aws-eks.git
synced 2026-01-15 16:23:58 +01:00
457 lines
18 KiB
HCL
457 lines
18 KiB
HCL
data "aws_partition" "current" {}
|
|
|
|
data "aws_caller_identity" "current" {}
|
|
|
|
################################################################################
|
|
# User Data
|
|
################################################################################
|
|
|
|
module "user_data" {
|
|
source = "../_user_data"
|
|
|
|
create = var.create
|
|
platform = var.platform
|
|
|
|
cluster_name = var.cluster_name
|
|
cluster_endpoint = var.cluster_endpoint
|
|
cluster_auth_base64 = var.cluster_auth_base64
|
|
|
|
cluster_service_ipv4_cidr = var.cluster_service_ipv4_cidr
|
|
|
|
enable_bootstrap_user_data = var.enable_bootstrap_user_data
|
|
pre_bootstrap_user_data = var.pre_bootstrap_user_data
|
|
post_bootstrap_user_data = var.post_bootstrap_user_data
|
|
bootstrap_extra_args = var.bootstrap_extra_args
|
|
user_data_template_path = var.user_data_template_path
|
|
}
|
|
|
|
################################################################################
|
|
# Launch template
|
|
################################################################################
|
|
|
|
locals {
|
|
# There are 4 scenarios here that have to be considered for `use_custom_launch_template`:
|
|
# 1. `var.create_launch_template = false && var.launch_template_name == ""` => EKS MNG will use its own default LT
|
|
# 2. `var.create_launch_template = false && var.launch_template_name == "something"` => User provided custom LT will be used
|
|
# 3. `var.create_launch_template = true && var.launch_template_name == ""` => Custom LT will be used, module will provide a default name
|
|
# 4. `var.create_launch_template = true && var.launch_template_name == "something"` => Custom LT will be used, LT name is provided by user
|
|
use_custom_launch_template = var.create_launch_template || var.launch_template_name != ""
|
|
|
|
launch_template_name_int = coalesce(var.launch_template_name, "${var.name}-eks-node-group")
|
|
|
|
security_group_ids = compact(concat([try(aws_security_group.this[0].id, ""), var.cluster_primary_security_group_id], var.vpc_security_group_ids))
|
|
}
|
|
|
|
resource "aws_launch_template" "this" {
|
|
count = var.create && var.create_launch_template ? 1 : 0
|
|
|
|
name = var.launch_template_use_name_prefix ? null : local.launch_template_name_int
|
|
name_prefix = var.launch_template_use_name_prefix ? "${local.launch_template_name_int}-" : null
|
|
description = var.launch_template_description
|
|
|
|
ebs_optimized = var.ebs_optimized
|
|
image_id = var.ami_id
|
|
# # Set on node group instead
|
|
# instance_type = var.launch_template_instance_type
|
|
key_name = var.key_name
|
|
user_data = module.user_data.user_data
|
|
|
|
vpc_security_group_ids = length(var.network_interfaces) > 0 ? [] : local.security_group_ids
|
|
|
|
default_version = var.launch_template_default_version
|
|
update_default_version = var.update_launch_template_default_version
|
|
disable_api_termination = var.disable_api_termination
|
|
# Set on EKS managed node group, will fail if set here
|
|
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics
|
|
# instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
|
|
kernel_id = var.kernel_id
|
|
ram_disk_id = var.ram_disk_id
|
|
|
|
dynamic "block_device_mappings" {
|
|
for_each = var.block_device_mappings
|
|
content {
|
|
device_name = block_device_mappings.value.device_name
|
|
no_device = lookup(block_device_mappings.value, "no_device", null)
|
|
virtual_name = lookup(block_device_mappings.value, "virtual_name", null)
|
|
|
|
dynamic "ebs" {
|
|
for_each = flatten([lookup(block_device_mappings.value, "ebs", [])])
|
|
content {
|
|
delete_on_termination = lookup(ebs.value, "delete_on_termination", null)
|
|
encrypted = lookup(ebs.value, "encrypted", null)
|
|
kms_key_id = lookup(ebs.value, "kms_key_id", null)
|
|
iops = lookup(ebs.value, "iops", null)
|
|
throughput = lookup(ebs.value, "throughput", null)
|
|
snapshot_id = lookup(ebs.value, "snapshot_id", null)
|
|
volume_size = lookup(ebs.value, "volume_size", null)
|
|
volume_type = lookup(ebs.value, "volume_type", null)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dynamic "capacity_reservation_specification" {
|
|
for_each = var.capacity_reservation_specification != null ? [var.capacity_reservation_specification] : []
|
|
content {
|
|
capacity_reservation_preference = lookup(capacity_reservation_specification.value, "capacity_reservation_preference", null)
|
|
|
|
dynamic "capacity_reservation_target" {
|
|
for_each = try([capacity_reservation_specification.value.capacity_reservation_target], [])
|
|
content {
|
|
capacity_reservation_id = lookup(capacity_reservation_target.value, "capacity_reservation_id", null)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dynamic "cpu_options" {
|
|
for_each = var.cpu_options != null ? [var.cpu_options] : []
|
|
content {
|
|
core_count = cpu_options.value.core_count
|
|
threads_per_core = cpu_options.value.threads_per_core
|
|
}
|
|
}
|
|
|
|
dynamic "credit_specification" {
|
|
for_each = var.credit_specification != null ? [var.credit_specification] : []
|
|
content {
|
|
cpu_credits = credit_specification.value.cpu_credits
|
|
}
|
|
}
|
|
|
|
dynamic "elastic_gpu_specifications" {
|
|
for_each = var.elastic_gpu_specifications != null ? [var.elastic_gpu_specifications] : []
|
|
content {
|
|
type = elastic_gpu_specifications.value.type
|
|
}
|
|
}
|
|
|
|
dynamic "elastic_inference_accelerator" {
|
|
for_each = var.elastic_inference_accelerator != null ? [var.elastic_inference_accelerator] : []
|
|
content {
|
|
type = elastic_inference_accelerator.value.type
|
|
}
|
|
}
|
|
|
|
dynamic "enclave_options" {
|
|
for_each = var.enclave_options != null ? [var.enclave_options] : []
|
|
content {
|
|
enabled = enclave_options.value.enabled
|
|
}
|
|
}
|
|
|
|
# Set on EKS managed node group, will fail if set here
|
|
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics
|
|
# dynamic "hibernation_options" {
|
|
# for_each = var.hibernation_options != null ? [var.hibernation_options] : []
|
|
# content {
|
|
# configured = hibernation_options.value.configured
|
|
# }
|
|
# }
|
|
|
|
# Set on EKS managed node group, will fail if set here
|
|
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics
|
|
# dynamic "iam_instance_profile" {
|
|
# for_each = [var.iam_instance_profile]
|
|
# content {
|
|
# name = lookup(var.iam_instance_profile, "name", null)
|
|
# arn = lookup(var.iam_instance_profile, "arn", null)
|
|
# }
|
|
# }
|
|
|
|
dynamic "instance_market_options" {
|
|
for_each = var.instance_market_options != null ? [var.instance_market_options] : []
|
|
content {
|
|
market_type = instance_market_options.value.market_type
|
|
|
|
dynamic "spot_options" {
|
|
for_each = lookup(instance_market_options.value, "spot_options", null) != null ? [instance_market_options.value.spot_options] : []
|
|
content {
|
|
block_duration_minutes = lookup(spot_options.value, "block_duration_minutes", null)
|
|
instance_interruption_behavior = lookup(spot_options.value, "instance_interruption_behavior", null)
|
|
max_price = lookup(spot_options.value, "max_price", null)
|
|
spot_instance_type = lookup(spot_options.value, "spot_instance_type", null)
|
|
valid_until = lookup(spot_options.value, "valid_until", null)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dynamic "license_specification" {
|
|
for_each = var.license_specifications != null ? [var.license_specifications] : []
|
|
content {
|
|
license_configuration_arn = license_specifications.value.license_configuration_arn
|
|
}
|
|
}
|
|
|
|
dynamic "metadata_options" {
|
|
for_each = var.metadata_options != null ? [var.metadata_options] : []
|
|
content {
|
|
http_endpoint = lookup(metadata_options.value, "http_endpoint", null)
|
|
http_tokens = lookup(metadata_options.value, "http_tokens", null)
|
|
http_put_response_hop_limit = lookup(metadata_options.value, "http_put_response_hop_limit", null)
|
|
http_protocol_ipv6 = lookup(metadata_options.value, "http_protocol_ipv6", null)
|
|
instance_metadata_tags = lookup(metadata_options.value, "instance_metadata_tags", null)
|
|
}
|
|
}
|
|
|
|
dynamic "monitoring" {
|
|
for_each = var.enable_monitoring != null ? [1] : []
|
|
content {
|
|
enabled = var.enable_monitoring
|
|
}
|
|
}
|
|
|
|
dynamic "network_interfaces" {
|
|
for_each = var.network_interfaces
|
|
content {
|
|
associate_carrier_ip_address = lookup(network_interfaces.value, "associate_carrier_ip_address", null)
|
|
associate_public_ip_address = lookup(network_interfaces.value, "associate_public_ip_address", null)
|
|
delete_on_termination = lookup(network_interfaces.value, "delete_on_termination", null)
|
|
description = lookup(network_interfaces.value, "description", null)
|
|
device_index = lookup(network_interfaces.value, "device_index", null)
|
|
interface_type = lookup(network_interfaces.value, "interface_type", null)
|
|
ipv4_addresses = try(network_interfaces.value.ipv4_addresses, [])
|
|
ipv4_address_count = lookup(network_interfaces.value, "ipv4_address_count", null)
|
|
ipv6_addresses = try(network_interfaces.value.ipv6_addresses, [])
|
|
ipv6_address_count = lookup(network_interfaces.value, "ipv6_address_count", null)
|
|
network_interface_id = lookup(network_interfaces.value, "network_interface_id", null)
|
|
private_ip_address = lookup(network_interfaces.value, "private_ip_address", null)
|
|
security_groups = compact(concat(try(network_interfaces.value.security_groups, []), local.security_group_ids))
|
|
# Set on EKS managed node group, will fail if set here
|
|
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics
|
|
# subnet_id = lookup(network_interfaces.value, "subnet_id", null)
|
|
}
|
|
}
|
|
|
|
dynamic "placement" {
|
|
for_each = var.placement != null ? [var.placement] : []
|
|
content {
|
|
affinity = lookup(placement.value, "affinity", null)
|
|
availability_zone = lookup(placement.value, "availability_zone", null)
|
|
group_name = lookup(placement.value, "group_name", null)
|
|
host_id = lookup(placement.value, "host_id", null)
|
|
spread_domain = lookup(placement.value, "spread_domain", null)
|
|
tenancy = lookup(placement.value, "tenancy", null)
|
|
partition_number = lookup(placement.value, "partition_number", null)
|
|
}
|
|
}
|
|
|
|
dynamic "tag_specifications" {
|
|
for_each = toset(["instance", "volume", "network-interface"])
|
|
content {
|
|
resource_type = tag_specifications.key
|
|
tags = merge(var.tags, { Name = var.name }, var.launch_template_tags)
|
|
}
|
|
}
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
|
|
# Prevent premature access of security group roles and policies by pods that
|
|
# require permissions on create/destroy that depend on nodes
|
|
depends_on = [
|
|
aws_security_group_rule.this,
|
|
aws_iam_role_policy_attachment.this,
|
|
]
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
################################################################################
|
|
# Node Group
|
|
################################################################################
|
|
|
|
locals {
|
|
launch_template_name = try(aws_launch_template.this[0].name, var.launch_template_name, null)
|
|
# Change order to allow users to set version priority before using defaults
|
|
launch_template_version = coalesce(var.launch_template_version, try(aws_launch_template.this[0].default_version, "$Default"))
|
|
}
|
|
|
|
resource "aws_eks_node_group" "this" {
|
|
count = var.create ? 1 : 0
|
|
|
|
# Required
|
|
cluster_name = var.cluster_name
|
|
node_role_arn = var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn
|
|
subnet_ids = var.subnet_ids
|
|
|
|
scaling_config {
|
|
min_size = var.min_size
|
|
max_size = var.max_size
|
|
desired_size = var.desired_size
|
|
}
|
|
|
|
# Optional
|
|
node_group_name = var.use_name_prefix ? null : var.name
|
|
node_group_name_prefix = var.use_name_prefix ? "${var.name}-" : null
|
|
|
|
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami
|
|
ami_type = var.ami_id != "" ? null : var.ami_type
|
|
release_version = var.ami_id != "" ? null : var.ami_release_version
|
|
version = var.ami_id != "" ? null : var.cluster_version
|
|
|
|
capacity_type = var.capacity_type
|
|
disk_size = local.use_custom_launch_template ? null : var.disk_size # if using LT, set disk size on LT or else it will error here
|
|
force_update_version = var.force_update_version
|
|
instance_types = var.instance_types
|
|
labels = var.labels
|
|
|
|
dynamic "launch_template" {
|
|
for_each = local.use_custom_launch_template ? [1] : []
|
|
content {
|
|
name = local.launch_template_name
|
|
version = local.launch_template_version
|
|
}
|
|
}
|
|
|
|
dynamic "remote_access" {
|
|
for_each = length(var.remote_access) > 0 ? [var.remote_access] : []
|
|
content {
|
|
ec2_ssh_key = try(remote_access.value.ec2_ssh_key, null)
|
|
source_security_group_ids = try(remote_access.value.source_security_group_ids, [])
|
|
}
|
|
}
|
|
|
|
dynamic "taint" {
|
|
for_each = var.taints
|
|
content {
|
|
key = taint.value.key
|
|
value = lookup(taint.value, "value")
|
|
effect = taint.value.effect
|
|
}
|
|
}
|
|
|
|
dynamic "update_config" {
|
|
for_each = length(var.update_config) > 0 ? [var.update_config] : []
|
|
content {
|
|
max_unavailable_percentage = try(update_config.value.max_unavailable_percentage, null)
|
|
max_unavailable = try(update_config.value.max_unavailable, null)
|
|
}
|
|
}
|
|
|
|
timeouts {
|
|
create = lookup(var.timeouts, "create", null)
|
|
update = lookup(var.timeouts, "update", null)
|
|
delete = lookup(var.timeouts, "delete", null)
|
|
}
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
ignore_changes = [
|
|
scaling_config[0].desired_size,
|
|
]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{ Name = var.name }
|
|
)
|
|
}
|
|
|
|
################################################################################
|
|
# Security Group
|
|
################################################################################
|
|
|
|
locals {
|
|
security_group_name = coalesce(var.security_group_name, "${var.name}-eks-node-group")
|
|
create_security_group = var.create && var.create_security_group
|
|
}
|
|
|
|
resource "aws_security_group" "this" {
|
|
count = local.create_security_group ? 1 : 0
|
|
|
|
name = var.security_group_use_name_prefix ? null : local.security_group_name
|
|
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
|
|
description = var.security_group_description
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{ "Name" = local.security_group_name },
|
|
var.security_group_tags
|
|
)
|
|
|
|
# https://github.com/hashicorp/terraform-provider-aws/issues/2445
|
|
# https://github.com/hashicorp/terraform-provider-aws/issues/9692
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_security_group_rule" "this" {
|
|
for_each = { for k, v in var.security_group_rules : k => v if local.create_security_group }
|
|
|
|
# Required
|
|
security_group_id = aws_security_group.this[0].id
|
|
protocol = each.value.protocol
|
|
from_port = each.value.from_port
|
|
to_port = each.value.to_port
|
|
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_cluster_security_group, false) ? var.cluster_security_group_id : null
|
|
)
|
|
}
|
|
|
|
################################################################################
|
|
# IAM Role
|
|
################################################################################
|
|
|
|
locals {
|
|
iam_role_name = coalesce(var.iam_role_name, "${var.name}-eks-node-group")
|
|
|
|
iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy"
|
|
|
|
cni_policy = var.cluster_ip_family == "ipv6" ? "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy" : "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "assume_role_policy" {
|
|
count = var.create && var.create_iam_role ? 1 : 0
|
|
|
|
statement {
|
|
sid = "EKSNodeAssumeRole"
|
|
actions = ["sts:AssumeRole"]
|
|
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["ec2.${data.aws_partition.current.dns_suffix}"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "this" {
|
|
count = var.create && var.create_iam_role ? 1 : 0
|
|
|
|
name = var.iam_role_use_name_prefix ? null : local.iam_role_name
|
|
name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null
|
|
path = var.iam_role_path
|
|
description = var.iam_role_description
|
|
|
|
assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json
|
|
permissions_boundary = var.iam_role_permissions_boundary
|
|
force_detach_policies = true
|
|
|
|
tags = merge(var.tags, var.iam_role_tags)
|
|
}
|
|
|
|
# Policies attached ref https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group
|
|
resource "aws_iam_role_policy_attachment" "this" {
|
|
for_each = var.create && var.create_iam_role ? toset(compact(distinct(concat([
|
|
"${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy",
|
|
"${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly",
|
|
var.iam_role_attach_cni_policy ? local.cni_policy : "",
|
|
], var.iam_role_additional_policies)))) : toset([])
|
|
|
|
policy_arn = each.value
|
|
role = aws_iam_role.this[0].name
|
|
}
|