Skip to content

Commit 959e533

Browse files
erksmax-rocket-internet
authored andcommitted
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
1 parent 613fb1c commit 959e533

File tree

10 files changed

+62
-14
lines changed

10 files changed

+62
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ project adheres to [Semantic Versioning](http://semver.org/).
1212
### Added
1313

1414
- Added support for custom service linked role for Auto Scaling group (by @voanhduy1512)
15+
- Added support for custom IAM roles for cluster and workers (by @erks)
1516
- Add cluster arn to outputs (by @alexsn)
1617
- Added outputs for `workers_user_data` and `workers_default_ami_id` (by @max-rocket-internet)
1718
- Added doc about spot instances (by @max-rocket-internet)

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ MIT Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-a
118118
| 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 |
119119
| cluster\_endpoint\_private\_access | Indicates whether or not the Amazon EKS private API server endpoint is enabled. | string | `"false"` | no |
120120
| cluster\_endpoint\_public\_access | Indicates whether or not the Amazon EKS public API server endpoint is enabled. | string | `"true"` | no |
121+
| cluster\_iam\_role\_name | IAM role name for the cluster. Only applicable if manage_cluster_iam_resources is set to false. | string | `""` | no |
121122
| cluster\_name | Name of the EKS cluster. Also used as a prefix in names of related resources. | string | n/a | yes |
122123
| 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 |
123124
| 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
130131
| kubeconfig\_name | Override the default name used for items kubeconfig. | string | `""` | no |
131132
| 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 |
132133
| manage\_aws\_auth | Whether to apply the aws-auth configmap file. | string | `"true"` | no |
134+
| 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 |
135+
| 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 |
133136
| 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 |
134137
| map\_accounts\_count | The count of accounts in the map_accounts list. | string | `"0"` | no |
135138
| map\_roles | Additional IAM roles to add to the aws-auth configmap. See examples/eks_test_fixture/variables.tf for example format. | list | `[]` | no |

aws_auth.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ data "template_file" "launch_template_worker_role_arns" {
3939
template = "${file("${path.module}/templates/worker-role.tpl")}"
4040

4141
vars {
42-
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)}"
42+
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)}"
4343
}
4444
}
4545

@@ -48,7 +48,7 @@ data "template_file" "worker_role_arns" {
4848
template = "${file("${path.module}/templates/worker-role.tpl")}"
4949

5050
vars {
51-
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${element(aws_iam_instance_profile.workers.*.role, count.index)}"
51+
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)}"
5252
}
5353
}
5454

cluster.tf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
resource "aws_eks_cluster" "this" {
22
name = "${var.cluster_name}"
33
enabled_cluster_log_types = "${var.cluster_enabled_log_types}"
4-
role_arn = "${aws_iam_role.cluster.arn}"
4+
role_arn = "${local.cluster_iam_role_arn}"
55
version = "${var.cluster_version}"
66

77
vpc_config {
@@ -58,14 +58,17 @@ resource "aws_iam_role" "cluster" {
5858
permissions_boundary = "${var.permissions_boundary}"
5959
path = "${var.iam_path}"
6060
force_detach_policies = true
61+
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
6162
}
6263

6364
resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSClusterPolicy" {
6465
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
6566
role = "${aws_iam_role.cluster.name}"
67+
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
6668
}
6769

6870
resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSServicePolicy" {
6971
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
7072
role = "${aws_iam_role.cluster.name}"
73+
count = "${var.manage_cluster_iam_resources ? 1 : 0}"
7174
}

data.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,18 @@ data "template_file" "launch_template_userdata" {
100100
kubelet_extra_args = "${lookup(var.worker_groups_launch_template[count.index], "kubelet_extra_args", local.workers_group_launch_template_defaults["kubelet_extra_args"])}"
101101
}
102102
}
103+
104+
data "aws_iam_role" "custom_cluster_iam_role" {
105+
name = "${var.cluster_iam_role_name}"
106+
count = "${var.manage_cluster_iam_resources ? 0 : 1}"
107+
}
108+
109+
data "aws_iam_instance_profile" "custom_worker_group_iam_instance_profile" {
110+
name = "${lookup(var.worker_groups[count.index], "iam_instance_profile_name", local.workers_group_defaults["iam_instance_profile_name"])}"
111+
count = "${var.manage_worker_iam_resources ? 0 : var.worker_group_count}"
112+
}
113+
114+
data "aws_iam_instance_profile" "custom_worker_group_launch_template_iam_instance_profile" {
115+
name = "${lookup(var.worker_groups_launch_template[count.index], "iam_instance_profile_name", local.workers_group_launch_template_defaults["iam_instance_profile_name"])}"
116+
count = "${var.manage_worker_iam_resources ? 0 : var.worker_group_launch_template_count}"
117+
}

local.tf

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ locals {
55
# to workaround terraform not supporting short circut evaluation
66
cluster_security_group_id = "${coalesce(join("", aws_security_group.cluster.*.id), var.cluster_security_group_id)}"
77

8+
cluster_iam_role_name = "${coalesce(join("", aws_iam_role.cluster.*.name), var.cluster_iam_role_name)}"
9+
cluster_iam_role_arn = "${coalesce(join("", aws_iam_role.cluster.*.arn), join("", data.aws_iam_role.custom_cluster_iam_role.*.arn))}"
10+
811
worker_security_group_id = "${coalesce(join("", aws_security_group.workers.*.id), var.worker_security_group_id)}"
912
default_iam_role_id = "${element(concat(aws_iam_role.workers.*.id, list("")), 0)}"
1013
kubeconfig_name = "${var.kubeconfig_name == "" ? "eks_${var.cluster_name}" : var.kubeconfig_name}"
@@ -34,7 +37,8 @@ locals {
3437
autoscaling_enabled = false # Sets whether policy and matching tags will be added to allow autoscaling.
3538
additional_security_group_ids = "" # A comma delimited list of additional security group ids to include in worker launch config
3639
protect_from_scale_in = false # Prevent AWS from scaling in, so that cluster-autoscaler is solely responsible.
37-
iam_role_id = "${local.default_iam_role_id}" # Use the specified IAM role if set.
40+
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.
41+
iam_role_id = "${local.default_iam_role_id}" # A custom IAM role id. Incompatible with iam_instance_profile_name.
3842
suspended_processes = "AZRebalance" # A comma delimited string of processes to to suspend. i.e. AZRebalance,HealthCheck,ReplaceUnhealthy
3943
target_group_arns = "" # A comma delimited list of ALB target group ARNs to be associated to the ASG
4044
enabled_metrics = "" # A comma delimited list of metrics to be collected i.e. GroupMinSize,GroupMaxSize,GroupDesiredCapacity
@@ -79,7 +83,8 @@ locals {
7983
autoscaling_enabled = false # Sets whether policy and matching tags will be added to allow autoscaling.
8084
additional_security_group_ids = "" # A comma delimited list of additional security group ids to include in worker launch config
8185
protect_from_scale_in = false # Prevent AWS from scaling in, so that cluster-autoscaler is solely responsible.
82-
iam_role_id = "${local.default_iam_role_id}" # Use the specified IAM role if set.
86+
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.
87+
iam_role_id = "${local.default_iam_role_id}" # A custom IAM role id. Incompatible with iam_instance_profile_name.
8388
suspended_processes = "AZRebalance" # A comma delimited string of processes to to suspend. i.e. AZRebalance,HealthCheck,ReplaceUnhealthy
8489
target_group_arns = "" # A comma delimited list of ALB target group ARNs to be associated to the ASG
8590
enabled_metrics = "" # A comma delimited list of metrics to be collected i.e. GroupMinSize,GroupMaxSize,GroupDesiredCapacity

outputs.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ output "config_map_aws_auth" {
3535

3636
output "cluster_iam_role_name" {
3737
description = "IAM role name of the EKS cluster."
38-
value = "${aws_iam_role.cluster.name}"
38+
value = "${local.cluster_iam_role_name}"
3939
}
4040

4141
output "cluster_iam_role_arn" {
4242
description = "IAM role ARN of the EKS cluster."
43-
value = "${aws_iam_role.cluster.arn}"
43+
value = "${local.cluster_iam_role_arn}"
4444
}
4545

4646
output "kubeconfig" {
@@ -105,10 +105,10 @@ output "worker_iam_instance_profile_names" {
105105

106106
output "worker_iam_role_name" {
107107
description = "default IAM role name for EKS worker groups"
108-
value = "${aws_iam_role.workers.name}"
108+
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)}"
109109
}
110110

111111
output "worker_iam_role_arn" {
112112
description = "default IAM role ARN for EKS worker groups"
113-
value = "${aws_iam_role.workers.arn}"
113+
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)}"
114114
}

variables.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,18 @@ variable "cluster_endpoint_public_access" {
257257
description = "Indicates whether or not the Amazon EKS public API server endpoint is enabled."
258258
default = true
259259
}
260+
261+
variable "manage_cluster_iam_resources" {
262+
description = "Whether to let the module manage cluster IAM resources. If set to false, cluster_iam_role_name must be specified."
263+
default = true
264+
}
265+
266+
variable "cluster_iam_role_name" {
267+
description = "IAM role name for the cluster. Only applicable if manage_cluster_iam_resources is set to false."
268+
default = ""
269+
}
270+
271+
variable "manage_worker_iam_resources" {
272+
description = "Whether to let the module manage worker IAM resources. If set to false, iam_instance_profile_name must be specified for workers."
273+
default = true
274+
}

workers.tf

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ resource "aws_launch_configuration" "workers" {
3838
name_prefix = "${aws_eks_cluster.this.name}-${lookup(var.worker_groups[count.index], "name", count.index)}"
3939
associate_public_ip_address = "${lookup(var.worker_groups[count.index], "public_ip", local.workers_group_defaults["public_ip"])}"
4040
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"])))}"]
41-
iam_instance_profile = "${element(aws_iam_instance_profile.workers.*.id, count.index)}"
41+
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)}"
4242
image_id = "${lookup(var.worker_groups[count.index], "ami_id", local.workers_group_defaults["ami_id"])}"
4343
instance_type = "${lookup(var.worker_groups[count.index], "instance_type", local.workers_group_defaults["instance_type"])}"
4444
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" {
131131
permissions_boundary = "${var.permissions_boundary}"
132132
path = "${var.iam_path}"
133133
force_detach_policies = true
134+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
134135
}
135136

136137
resource "aws_iam_instance_profile" "workers" {
137138
name_prefix = "${aws_eks_cluster.this.name}"
138139
role = "${lookup(var.worker_groups[count.index], "iam_role_id", lookup(local.workers_group_defaults, "iam_role_id"))}"
139-
count = "${var.worker_group_count}"
140+
count = "${var.manage_worker_iam_resources ? var.worker_group_count : 0}"
140141
path = "${var.iam_path}"
141142
}
142143

143144
resource "aws_iam_role_policy_attachment" "workers_AmazonEKSWorkerNodePolicy" {
144145
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
145146
role = "${aws_iam_role.workers.name}"
147+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
146148
}
147149

148150
resource "aws_iam_role_policy_attachment" "workers_AmazonEKS_CNI_Policy" {
149151
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
150152
role = "${aws_iam_role.workers.name}"
153+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
151154
}
152155

153156
resource "aws_iam_role_policy_attachment" "workers_AmazonEC2ContainerRegistryReadOnly" {
154157
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
155158
role = "${aws_iam_role.workers.name}"
159+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
156160
}
157161

158162
resource "aws_iam_role_policy_attachment" "workers_additional_policies" {
159-
count = "${var.workers_additional_policies_count}"
163+
count = "${var.manage_worker_iam_resources ? var.workers_additional_policies_count : 0}"
160164
role = "${aws_iam_role.workers.name}"
161165
policy_arn = "${var.workers_additional_policies[count.index]}"
162166
}
@@ -174,13 +178,15 @@ resource "null_resource" "tags_as_list_of_maps" {
174178
resource "aws_iam_role_policy_attachment" "workers_autoscaling" {
175179
policy_arn = "${aws_iam_policy.worker_autoscaling.arn}"
176180
role = "${aws_iam_role.workers.name}"
181+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
177182
}
178183

179184
resource "aws_iam_policy" "worker_autoscaling" {
180185
name_prefix = "eks-worker-autoscaling-${aws_eks_cluster.this.name}"
181186
description = "EKS worker node autoscaling policy for cluster ${aws_eks_cluster.this.name}"
182187
policy = "${data.aws_iam_policy_document.worker_autoscaling.json}"
183188
path = "${var.iam_path}"
189+
count = "${var.manage_worker_iam_resources ? 1 : 0}"
184190
}
185191

186192
data "aws_iam_policy_document" "worker_autoscaling" {

workers_launch_template.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ resource "aws_launch_template" "workers_launch_template" {
7575
}
7676

7777
iam_instance_profile {
78-
name = "${element(aws_iam_instance_profile.workers_launch_template.*.name, count.index)}"
78+
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)}"
7979
}
8080

8181
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" {
118118
resource "aws_iam_instance_profile" "workers_launch_template" {
119119
name_prefix = "${aws_eks_cluster.this.name}"
120120
role = "${lookup(var.worker_groups_launch_template[count.index], "iam_role_id", lookup(local.workers_group_launch_template_defaults, "iam_role_id"))}"
121-
count = "${var.worker_group_launch_template_count}"
121+
count = "${var.manage_worker_iam_resources ? var.worker_group_launch_template_count : 0}"
122122
path = "${var.iam_path}"
123123
}

0 commit comments

Comments
 (0)