diff --git a/CHANGELOG.md b/CHANGELOG.md index 4111f0c..fb343ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Added - **Breaking:** Allow for specifying a custom AMI for the worker nodes. (by @bmcstdio) +- Added support for Windows workers AMIs (by @hodduc) - Write your awesome addition here (by @you) ### Changed diff --git a/README.md b/README.md index f2fc94c..edcc733 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,9 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a | vpc\_id | VPC where the cluster and workers will be deployed. | string | n/a | yes | | worker\_additional\_security\_group\_ids | A list of additional security group ids to attach to worker instances | list(string) | `[]` | no | | worker\_ami\_name\_filter | Name filter for AWS EKS worker AMI. If not provided, the latest official AMI for the specified 'cluster_version' is used. | string | `""` | no | +| worker\_ami\_name\_filter\_windows | Name filter for AWS EKS Windows worker AMI. If not provided, the latest official AMI for the specified 'cluster_version' is used. | string | `""` | no | | worker\_ami\_owner\_id | The ID of the owner for the AMI to use for the AWS EKS workers. Valid values are an AWS account ID, 'self' (the current account), or an AWS owner alias (e.g. 'amazon', 'aws-marketplace', 'microsoft'). | string | `"602401143452"` | no | +| worker\_ami\_owner\_id\_windows | The ID of the owner for the AMI to use for the AWS EKS Windows workers. Valid values are an AWS account ID, 'self' (the current account), or an AWS owner alias (e.g. 'amazon', 'aws-marketplace', 'microsoft'). | string | `"801119661308"` | no | | worker\_create\_initial\_lifecycle\_hooks | Whether to create initial lifecycle hooks provided in worker groups. | bool | `"false"` | no | | worker\_create\_security\_group | Whether to create a security group for the workers or attach the workers to `worker_security_group_id`. | bool | `"true"` | no | | worker\_groups | A list of maps defining worker group configurations to be defined using AWS Launch Configurations. See workers_group_defaults for valid keys. | any | `[]` | no | diff --git a/aws_auth.tf b/aws_auth.tf index d653110..bd32211 100644 --- a/aws_auth.tf +++ b/aws_auth.tf @@ -47,6 +47,11 @@ data "template_file" "launch_template_worker_role_arns" { ), count.index, )}" + platform = lookup( + var.worker_groups_launch_template[count.index], + "platform", + local.workers_group_defaults["platform"] + ) } } @@ -63,6 +68,11 @@ data "template_file" "worker_role_arns" { ), count.index, )}" + platform = lookup( + var.worker_groups[count.index], + "platform", + local.workers_group_defaults["platform"] + ) } } diff --git a/data.tf b/data.tf index 1a28e25..8fee32f 100644 --- a/data.tf +++ b/data.tf @@ -1,5 +1,6 @@ locals { - worker_ami_name_filter = var.worker_ami_name_filter != "" ? var.worker_ami_name_filter : "amazon-eks-node-${var.cluster_version}-v*" + worker_ami_name_filter = var.worker_ami_name_filter != "" ? var.worker_ami_name_filter : "amazon-eks-node-${var.cluster_version}-v*" + worker_ami_name_filter_windows = var.worker_ami_name_filter_windows != "" ? var.worker_ami_name_filter_windows : "Windows_Server-2019-English-Core-EKS_Optimized-${var.cluster_version}-*" } data "aws_iam_policy_document" "workers_assume_role_policy" { @@ -28,6 +29,24 @@ data "aws_ami" "eks_worker" { owners = [var.worker_ami_owner_id] } +data "aws_ami" "eks_worker_windows" { + filter { + name = "name" + values = [local.worker_ami_name_filter_windows] + } + + filter { + name = "platform" + values = ["windows"] + } + + most_recent = true + + # Owner ID of AWS EKS team (windows) + owners = [var.worker_ami_owner_id_windows] +} + + data "aws_iam_policy_document" "cluster_assume_role_policy" { statement { sid = "EKSClusterAssumeRole" @@ -85,8 +104,12 @@ EOF } data "template_file" "userdata" { - count = local.worker_group_count - template = file("${path.module}/templates/userdata.sh.tpl") + count = local.worker_group_count + template = file( + lookup(var.worker_groups[count.index], "platform", local.workers_group_defaults["platform"]) == "windows" ? + "${path.module}/templates/userdata_windows.tpl" : + "${path.module}/templates/userdata.sh.tpl" + ) vars = { cluster_name = aws_eks_cluster.this.name @@ -116,8 +139,12 @@ data "template_file" "userdata" { } data "template_file" "launch_template_userdata" { - count = local.worker_group_launch_template_count - template = file("${path.module}/templates/userdata.sh.tpl") + count = local.worker_group_launch_template_count + template = file( + lookup(var.worker_groups_launch_template[count.index], "platform", local.workers_group_defaults["platform"]) == "windows" ? + "${path.module}/templates/userdata_windows.tpl" : + "${path.module}/templates/userdata.sh.tpl" + ) vars = { cluster_name = aws_eks_cluster.this.name diff --git a/docs/faq.md b/docs/faq.md index 089ce34..d793f28 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -98,3 +98,9 @@ module "eks" { # ... } ``` + +## How can I use Windows workers? + +To enable Windows support for your EKS cluster, you should apply some configs manually. See the [Enabling Windows Support (Windows/MacOS/Linux)](https://docs.aws.amazon.com/eks/latest/userguide/windows-support.html#enable-windows-support). + +Windows worker nodes requires additional cluster role (eks:kube-proxy-windows). If you are adding windows workers to existing cluster, you should apply config-map-aws-auth again. diff --git a/local.tf b/local.tf index 9bf6d18..7a4b457 100644 --- a/local.tf +++ b/local.tf @@ -19,10 +19,13 @@ locals { worker_group_count = length(var.worker_groups) worker_group_launch_template_count = length(var.worker_groups_launch_template) + default_ami_id_linux = data.aws_ami.eks_worker.id + default_ami_id_windows = data.aws_ami.eks_worker_windows.id + workers_group_defaults_defaults = { name = "count.index" # Name of the worker group. Literal count.index will never be used but if name is not set, the count.index interpolation will be used. tags = [] # A list of map defining extra tags to be applied to the worker group autoscaling group. - ami_id = data.aws_ami.eks_worker.id # AMI ID for the eks workers. If none is provided, Terraform will search for the latest version of their EKS optimized worker AMI. + ami_id = "" # AMI ID for the eks workers. If none is provided, Terraform will search for the latest version of their EKS optimized worker AMI based on platform. asg_desired_capacity = "1" # Desired worker capacity in the autoscaling group and changing its value will not affect the autoscaling group's desired capacity because the cluster-autoscaler manages up and down scaling of the nodes. Cluster-autoscaler add nodes when pods are in pending state and remove the nodes when they are not required by modifying the desirec_capacity of the autoscaling group. Although an issue exists in which if the value of the asg_min_size is changed it modifies the value of asg_desired_capacity. asg_max_size = "3" # Maximum worker capacity in the autoscaling group. asg_min_size = "1" # Minimum worker capacity in the autoscaling group. NOTE: Change in this paramater will affect the asg_desired_capacity, like changing its value to 2 will change asg_desired_capacity value to 2 but bringing back it to 1 will not affect the asg_desired_capacity. @@ -55,6 +58,7 @@ locals { placement_group = "" # The name of the placement group into which to launch the instances, if any. service_linked_role_arn = "" # Arn of custom service linked role that Auto Scaling group will use. Useful when you have encrypted EBS termination_policies = [] # A list of policies to decide how the instances in the auto scale group should be terminated. + platform = "linux" # Platform of workers. either "linux" or "windows" # Settings for launch templates root_block_device_name = data.aws_ami.eks_worker.root_device_name # Root device name for workers. If non is provided, will assume default AMI was used. root_kms_key_id = "" # The KMS key to use when encrypting the root storage device diff --git a/templates/userdata_windows.tpl b/templates/userdata_windows.tpl new file mode 100644 index 0000000..61be8e8 --- /dev/null +++ b/templates/userdata_windows.tpl @@ -0,0 +1,11 @@ + +${pre_userdata} + +[string]$EKSBinDir = "$env:ProgramFiles\Amazon\EKS" +[string]$EKSBootstrapScriptName = 'Start-EKSBootstrap.ps1' +[string]$EKSBootstrapScriptFile = "$EKSBinDir\$EKSBootstrapScriptName" +& $EKSBootstrapScriptFile -EKSClusterName ${cluster_name} -KubeletExtraArgs '${kubelet_extra_args}' 3>&1 4>&1 5>&1 6>&1 +$LastError = if ($?) { 0 } else { $Error[0].Exception.HResult } + +${additional_userdata} + diff --git a/templates/worker-role.tpl b/templates/worker-role.tpl index 2a9af58..f5a00d6 100644 --- a/templates/worker-role.tpl +++ b/templates/worker-role.tpl @@ -3,3 +3,6 @@ groups: - system:bootstrappers - system:nodes + %{~ if platform == "windows" ~} + - eks:kube-proxy-windows + %{~ endif ~} diff --git a/variables.tf b/variables.tf index a4d2d4d..9161856 100644 --- a/variables.tf +++ b/variables.tf @@ -126,12 +126,24 @@ variable "worker_ami_name_filter" { default = "" } +variable "worker_ami_name_filter_windows" { + description = "Name filter for AWS EKS Windows worker AMI. If not provided, the latest official AMI for the specified 'cluster_version' is used." + type = string + default = "" +} + variable "worker_ami_owner_id" { description = "The ID of the owner for the AMI to use for the AWS EKS workers. Valid values are an AWS account ID, 'self' (the current account), or an AWS owner alias (e.g. 'amazon', 'aws-marketplace', 'microsoft')." type = string default = "602401143452" // The ID of the owner of the official AWS EKS AMIs. } +variable "worker_ami_owner_id_windows" { + description = "The ID of the owner for the AMI to use for the AWS EKS Windows workers. Valid values are an AWS account ID, 'self' (the current account), or an AWS owner alias (e.g. 'amazon', 'aws-marketplace', 'microsoft')." + type = string + default = "801119661308" // The ID of the owner of the official AWS EKS Windows AMIs. +} + variable "worker_additional_security_group_ids" { description = "A list of additional security group ids to attach to worker instances" type = list(string) diff --git a/workers.tf b/workers.tf index ca0bd72..a59800d 100644 --- a/workers.tf +++ b/workers.tf @@ -166,7 +166,7 @@ resource "aws_launch_configuration" "workers" { image_id = lookup( var.worker_groups[count.index], "ami_id", - local.workers_group_defaults["ami_id"], + lookup(var.worker_groups[count.index], "platform", local.workers_group_defaults["platform"]) == "windows" ? local.default_ami_id_windows : local.default_ami_id_linux, ) instance_type = lookup( var.worker_groups[count.index], diff --git a/workers_launch_template.tf b/workers_launch_template.tf index 6bb6437..fefacd6 100644 --- a/workers_launch_template.tf +++ b/workers_launch_template.tf @@ -257,7 +257,7 @@ resource "aws_launch_template" "workers_launch_template" { image_id = lookup( var.worker_groups_launch_template[count.index], "ami_id", - local.workers_group_defaults["ami_id"], + lookup(var.worker_groups_launch_template[count.index], "platform", local.workers_group_defaults["platform"]) == "windows" ? local.default_ami_id_windows : local.default_ami_id_linux, ) instance_type = lookup( var.worker_groups_launch_template[count.index],