Support custom IAM roles for cluster and workers (#338)

* allow specifying custom worker IAM instance profiles

* allow specifying custom cluster IAM role

* add doc

* update changelog

* use data.aws_iam_instance_profile.name
This commit is contained in:
Touch Ungboriboonpisal
2019-05-07 05:46:06 -07:00
committed by Max Williams
parent 613fb1ca96
commit 959e5330e3
10 changed files with 62 additions and 14 deletions

View File

@@ -12,6 +12,7 @@ project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Added support for custom service linked role for Auto Scaling group (by @voanhduy1512)
- Added support for custom IAM roles for cluster and workers (by @erks)
- Add cluster arn to outputs (by @alexsn)
- Added outputs for `workers_user_data` and `workers_default_ami_id` (by @max-rocket-internet)
- Added doc about spot instances (by @max-rocket-internet)

View File

@@ -118,6 +118,7 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a
| cluster\_enabled\_log\_types | A list of the desired control plane logging to enable. For more information, see Amazon EKS Control Plane Logging documentation (https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html) | list | `[]` | no |
| cluster\_endpoint\_private\_access | Indicates whether or not the Amazon EKS private API server endpoint is enabled. | string | `"false"` | no |
| cluster\_endpoint\_public\_access | Indicates whether or not the Amazon EKS public API server endpoint is enabled. | string | `"true"` | no |
| cluster\_iam\_role\_name | IAM role name for the cluster. Only applicable if manage_cluster_iam_resources is set to false. | string | `""` | no |
| cluster\_name | Name of the EKS cluster. Also used as a prefix in names of related resources. | string | n/a | yes |
| cluster\_security\_group\_id | If provided, the EKS cluster will be attached to this security group. If not given, a security group will be created with necessary ingres/egress to work with the workers and provide API access to your current IP/32. | string | `""` | no |
| cluster\_version | Kubernetes version to use for the EKS cluster. | string | `"1.12"` | no |
@@ -130,6 +131,8 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a
| kubeconfig\_name | Override the default name used for items kubeconfig. | string | `""` | no |
| local\_exec\_interpreter | Command to run for local-exec resources. Must be a shell-style interpreter. If you are on Windows Git Bash is a good choice. | list | `[ "/bin/sh", "-c" ]` | no |
| manage\_aws\_auth | Whether to apply the aws-auth configmap file. | string | `"true"` | no |
| manage\_cluster\_iam\_resources | Whether to let the module manage cluster IAM resources. If set to false, cluster_iam_role_name must be specified. | string | `"true"` | no |
| manage\_worker\_iam\_resources | Whether to let the module manage worker IAM resources. If set to false, iam_instance_profile_name must be specified for workers. | string | `"true"` | no |
| map\_accounts | Additional AWS account numbers to add to the aws-auth configmap. See examples/eks_test_fixture/variables.tf for example format. | list | `[]` | no |
| map\_accounts\_count | The count of accounts in the map_accounts list. | string | `"0"` | no |
| map\_roles | Additional IAM roles to add to the aws-auth configmap. See examples/eks_test_fixture/variables.tf for example format. | list | `[]` | no |

View File

@@ -39,7 +39,7 @@ data "template_file" "launch_template_worker_role_arns" {
template = "${file("${path.module}/templates/worker-role.tpl")}"
vars {
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${element(aws_iam_instance_profile.workers_launch_template.*.role, count.index)}"
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${element(coalescelist(aws_iam_instance_profile.workers_launch_template.*.role, data.aws_iam_instance_profile.custom_worker_group_launch_template_iam_instance_profile.*.role_name), count.index)}"
}
}
@@ -48,7 +48,7 @@ data "template_file" "worker_role_arns" {
template = "${file("${path.module}/templates/worker-role.tpl")}"
vars {
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${element(aws_iam_instance_profile.workers.*.role, count.index)}"
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${element(coalescelist(aws_iam_instance_profile.workers.*.role, data.aws_iam_instance_profile.custom_worker_group_iam_instance_profile.*.role_name), count.index)}"
}
}

View File

@@ -1,7 +1,7 @@
resource "aws_eks_cluster" "this" {
name = "${var.cluster_name}"
enabled_cluster_log_types = "${var.cluster_enabled_log_types}"
role_arn = "${aws_iam_role.cluster.arn}"
role_arn = "${local.cluster_iam_role_arn}"
version = "${var.cluster_version}"
vpc_config {
@@ -58,14 +58,17 @@ resource "aws_iam_role" "cluster" {
permissions_boundary = "${var.permissions_boundary}"
path = "${var.iam_path}"
force_detach_policies = true
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
}
resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = "${aws_iam_role.cluster.name}"
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
}
resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSServicePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
role = "${aws_iam_role.cluster.name}"
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
}

15
data.tf
View File

@@ -100,3 +100,18 @@ data "template_file" "launch_template_userdata" {
kubelet_extra_args = "${lookup(var.worker_groups_launch_template[count.index], "kubelet_extra_args", local.workers_group_launch_template_defaults["kubelet_extra_args"])}"
}
}
data "aws_iam_role" "custom_cluster_iam_role" {
name = "${var.cluster_iam_role_name}"
count = "${var.manage_cluster_iam_resources ? 0 : 1}"
}
data "aws_iam_instance_profile" "custom_worker_group_iam_instance_profile" {
name = "${lookup(var.worker_groups[count.index], "iam_instance_profile_name", local.workers_group_defaults["iam_instance_profile_name"])}"
count = "${var.manage_worker_iam_resources ? 0 : var.worker_group_count}"
}
data "aws_iam_instance_profile" "custom_worker_group_launch_template_iam_instance_profile" {
name = "${lookup(var.worker_groups_launch_template[count.index], "iam_instance_profile_name", local.workers_group_launch_template_defaults["iam_instance_profile_name"])}"
count = "${var.manage_worker_iam_resources ? 0 : var.worker_group_launch_template_count}"
}

View File

@@ -5,6 +5,9 @@ locals {
# to workaround terraform not supporting short circut evaluation
cluster_security_group_id = "${coalesce(join("", aws_security_group.cluster.*.id), var.cluster_security_group_id)}"
cluster_iam_role_name = "${coalesce(join("", aws_iam_role.cluster.*.name), var.cluster_iam_role_name)}"
cluster_iam_role_arn = "${coalesce(join("", aws_iam_role.cluster.*.arn), join("", data.aws_iam_role.custom_cluster_iam_role.*.arn))}"
worker_security_group_id = "${coalesce(join("", aws_security_group.workers.*.id), var.worker_security_group_id)}"
default_iam_role_id = "${element(concat(aws_iam_role.workers.*.id, list("")), 0)}"
kubeconfig_name = "${var.kubeconfig_name == "" ? "eks_${var.cluster_name}" : var.kubeconfig_name}"
@@ -34,7 +37,8 @@ locals {
autoscaling_enabled = false # Sets whether policy and matching tags will be added to allow autoscaling.
additional_security_group_ids = "" # A comma delimited list of additional security group ids to include in worker launch config
protect_from_scale_in = false # Prevent AWS from scaling in, so that cluster-autoscaler is solely responsible.
iam_role_id = "${local.default_iam_role_id}" # Use the specified IAM role if set.
iam_instance_profile_name = "" # A custom IAM instance profile name. Used when manage_worker_iam_resources is set to false. Incompatible with iam_role_id.
iam_role_id = "${local.default_iam_role_id}" # A custom IAM role id. Incompatible with iam_instance_profile_name.
suspended_processes = "AZRebalance" # A comma delimited string of processes to to suspend. i.e. AZRebalance,HealthCheck,ReplaceUnhealthy
target_group_arns = "" # A comma delimited list of ALB target group ARNs to be associated to the ASG
enabled_metrics = "" # A comma delimited list of metrics to be collected i.e. GroupMinSize,GroupMaxSize,GroupDesiredCapacity
@@ -79,7 +83,8 @@ locals {
autoscaling_enabled = false # Sets whether policy and matching tags will be added to allow autoscaling.
additional_security_group_ids = "" # A comma delimited list of additional security group ids to include in worker launch config
protect_from_scale_in = false # Prevent AWS from scaling in, so that cluster-autoscaler is solely responsible.
iam_role_id = "${local.default_iam_role_id}" # Use the specified IAM role if set.
iam_instance_profile_name = "" # A custom IAM instance profile name. Used when manage_worker_iam_resources is set to false. Incompatible with iam_role_id.
iam_role_id = "${local.default_iam_role_id}" # A custom IAM role id. Incompatible with iam_instance_profile_name.
suspended_processes = "AZRebalance" # A comma delimited string of processes to to suspend. i.e. AZRebalance,HealthCheck,ReplaceUnhealthy
target_group_arns = "" # A comma delimited list of ALB target group ARNs to be associated to the ASG
enabled_metrics = "" # A comma delimited list of metrics to be collected i.e. GroupMinSize,GroupMaxSize,GroupDesiredCapacity

View File

@@ -35,12 +35,12 @@ output "config_map_aws_auth" {
output "cluster_iam_role_name" {
description = "IAM role name of the EKS cluster."
value = "${aws_iam_role.cluster.name}"
value = "${local.cluster_iam_role_name}"
}
output "cluster_iam_role_arn" {
description = "IAM role ARN of the EKS cluster."
value = "${aws_iam_role.cluster.arn}"
value = "${local.cluster_iam_role_arn}"
}
output "kubeconfig" {
@@ -105,10 +105,10 @@ output "worker_iam_instance_profile_names" {
output "worker_iam_role_name" {
description = "default IAM role name for EKS worker groups"
value = "${aws_iam_role.workers.name}"
value = "${element(coalescelist(aws_iam_role.workers.*.name, data.aws_iam_instance_profile.custom_worker_group_iam_instance_profile.*.role_name, data.aws_iam_instance_profile.custom_worker_group_launch_template_iam_instance_profile.*.role_name), 0)}"
}
output "worker_iam_role_arn" {
description = "default IAM role ARN for EKS worker groups"
value = "${aws_iam_role.workers.arn}"
value = "${element(coalescelist(aws_iam_role.workers.*.arn, data.aws_iam_instance_profile.custom_worker_group_iam_instance_profile.*.role_arn, data.aws_iam_instance_profile.custom_worker_group_launch_template_iam_instance_profile.*.role_arn), 0)}"
}

View File

@@ -257,3 +257,18 @@ variable "cluster_endpoint_public_access" {
description = "Indicates whether or not the Amazon EKS public API server endpoint is enabled."
default = true
}
variable "manage_cluster_iam_resources" {
description = "Whether to let the module manage cluster IAM resources. If set to false, cluster_iam_role_name must be specified."
default = true
}
variable "cluster_iam_role_name" {
description = "IAM role name for the cluster. Only applicable if manage_cluster_iam_resources is set to false."
default = ""
}
variable "manage_worker_iam_resources" {
description = "Whether to let the module manage worker IAM resources. If set to false, iam_instance_profile_name must be specified for workers."
default = true
}

View File

@@ -38,7 +38,7 @@ resource "aws_launch_configuration" "workers" {
name_prefix = "${aws_eks_cluster.this.name}-${lookup(var.worker_groups[count.index], "name", count.index)}"
associate_public_ip_address = "${lookup(var.worker_groups[count.index], "public_ip", local.workers_group_defaults["public_ip"])}"
security_groups = ["${local.worker_security_group_id}", "${var.worker_additional_security_group_ids}", "${compact(split(",",lookup(var.worker_groups[count.index],"additional_security_group_ids", local.workers_group_defaults["additional_security_group_ids"])))}"]
iam_instance_profile = "${element(aws_iam_instance_profile.workers.*.id, count.index)}"
iam_instance_profile = "${element(coalescelist(aws_iam_instance_profile.workers.*.id, data.aws_iam_instance_profile.custom_worker_group_iam_instance_profile.*.name), count.index)}"
image_id = "${lookup(var.worker_groups[count.index], "ami_id", local.workers_group_defaults["ami_id"])}"
instance_type = "${lookup(var.worker_groups[count.index], "instance_type", local.workers_group_defaults["instance_type"])}"
key_name = "${lookup(var.worker_groups[count.index], "key_name", local.workers_group_defaults["key_name"])}"
@@ -131,32 +131,36 @@ resource "aws_iam_role" "workers" {
permissions_boundary = "${var.permissions_boundary}"
path = "${var.iam_path}"
force_detach_policies = true
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
resource "aws_iam_instance_profile" "workers" {
name_prefix = "${aws_eks_cluster.this.name}"
role = "${lookup(var.worker_groups[count.index], "iam_role_id", lookup(local.workers_group_defaults, "iam_role_id"))}"
count = "${var.worker_group_count}"
count = "${var.manage_worker_iam_resources ? var.worker_group_count : 0}"
path = "${var.iam_path}"
}
resource "aws_iam_role_policy_attachment" "workers_AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = "${aws_iam_role.workers.name}"
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
resource "aws_iam_role_policy_attachment" "workers_AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = "${aws_iam_role.workers.name}"
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
resource "aws_iam_role_policy_attachment" "workers_AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = "${aws_iam_role.workers.name}"
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
resource "aws_iam_role_policy_attachment" "workers_additional_policies" {
count = "${var.workers_additional_policies_count}"
count = "${var.manage_worker_iam_resources ? var.workers_additional_policies_count : 0}"
role = "${aws_iam_role.workers.name}"
policy_arn = "${var.workers_additional_policies[count.index]}"
}
@@ -174,6 +178,7 @@ resource "null_resource" "tags_as_list_of_maps" {
resource "aws_iam_role_policy_attachment" "workers_autoscaling" {
policy_arn = "${aws_iam_policy.worker_autoscaling.arn}"
role = "${aws_iam_role.workers.name}"
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
resource "aws_iam_policy" "worker_autoscaling" {
@@ -181,6 +186,7 @@ resource "aws_iam_policy" "worker_autoscaling" {
description = "EKS worker node autoscaling policy for cluster ${aws_eks_cluster.this.name}"
policy = "${data.aws_iam_policy_document.worker_autoscaling.json}"
path = "${var.iam_path}"
count = "${var.manage_worker_iam_resources ? 1 : 0}"
}
data "aws_iam_policy_document" "worker_autoscaling" {

View File

@@ -75,7 +75,7 @@ resource "aws_launch_template" "workers_launch_template" {
}
iam_instance_profile {
name = "${element(aws_iam_instance_profile.workers_launch_template.*.name, count.index)}"
name = "${element(coalescelist(aws_iam_instance_profile.workers_launch_template.*.name, data.aws_iam_instance_profile.custom_worker_group_launch_template_iam_instance_profile.*.name), count.index)}"
}
image_id = "${lookup(var.worker_groups_launch_template[count.index], "ami_id", local.workers_group_launch_template_defaults["ami_id"])}"
@@ -118,6 +118,6 @@ resource "aws_launch_template" "workers_launch_template" {
resource "aws_iam_instance_profile" "workers_launch_template" {
name_prefix = "${aws_eks_cluster.this.name}"
role = "${lookup(var.worker_groups_launch_template[count.index], "iam_role_id", lookup(local.workers_group_launch_template_defaults, "iam_role_id"))}"
count = "${var.worker_group_launch_template_count}"
count = "${var.manage_worker_iam_resources ? var.worker_group_launch_template_count : 0}"
path = "${var.iam_path}"
}