Skip to content

Commit 1604c6c

Browse files
authored
feat: Add support for custom IAM role policy (#3087)
1 parent 17448b4 commit 1604c6c

File tree

15 files changed

+314
-1
lines changed

15 files changed

+314
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/antonbabenko/pre-commit-terraform
3-
rev: v1.91.0
3+
rev: v1.92.0
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_docs

modules/eks-managed-node-group/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ module "eks_managed_node_group" {
8585
| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
8686
| [aws_eks_node_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group) | resource |
8787
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
88+
| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
8889
| [aws_iam_role_policy_attachment.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
8990
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
9091
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
@@ -93,6 +94,7 @@ module "eks_managed_node_group" {
9394
| [aws_ec2_instance_type.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type) | data source |
9495
| [aws_ec2_instance_type_offerings.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type_offerings) | data source |
9596
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
97+
| [aws_iam_policy_document.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
9698
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
9799
| [aws_ssm_parameter.ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
98100
| [aws_subnets.efa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
@@ -121,6 +123,7 @@ module "eks_managed_node_group" {
121123
| <a name="input_cpu_options"></a> [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | `map(string)` | `{}` | no |
122124
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create EKS managed node group or not | `bool` | `true` | no |
123125
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
126+
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
124127
| <a name="input_create_launch_template"></a> [create\_launch\_template](#input\_create\_launch\_template) | Determines whether to create a launch template or not. If set to `false`, EKS will use its own default launch template | `bool` | `true` | no |
125128
| <a name="input_create_placement_group"></a> [create\_placement\_group](#input\_create\_placement\_group) | Determines whether a placement group is created & used by the node group | `bool` | `false` | no |
126129
| <a name="input_create_schedule"></a> [create\_schedule](#input\_create\_schedule) | Determines whether to create autoscaling group schedule or not | `bool` | `true` | no |
@@ -143,6 +146,7 @@ module "eks_managed_node_group" {
143146
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no |
144147
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
145148
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
149+
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
146150
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no |
147151
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
148152
| <a name="input_instance_market_options"></a> [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | `any` | `{}` | no |

modules/eks-managed-node-group/main.tf

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ resource "aws_launch_template" "this" {
325325
# require permissions on create/destroy that depend on nodes
326326
depends_on = [
327327
aws_iam_role_policy_attachment.this,
328+
aws_iam_role_policy_attachment.additional,
328329
]
329330

330331
lifecycle {
@@ -535,6 +536,68 @@ resource "aws_iam_role_policy_attachment" "additional" {
535536
role = aws_iam_role.this[0].name
536537
}
537538

539+
################################################################################
540+
# IAM Role Policy
541+
################################################################################
542+
543+
locals {
544+
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && length(var.iam_role_policy_statements) > 0
545+
}
546+
547+
data "aws_iam_policy_document" "role" {
548+
count = local.create_iam_role_policy ? 1 : 0
549+
550+
dynamic "statement" {
551+
for_each = var.iam_role_policy_statements
552+
553+
content {
554+
sid = try(statement.value.sid, null)
555+
actions = try(statement.value.actions, null)
556+
not_actions = try(statement.value.not_actions, null)
557+
effect = try(statement.value.effect, null)
558+
resources = try(statement.value.resources, null)
559+
not_resources = try(statement.value.not_resources, null)
560+
561+
dynamic "principals" {
562+
for_each = try(statement.value.principals, [])
563+
564+
content {
565+
type = principals.value.type
566+
identifiers = principals.value.identifiers
567+
}
568+
}
569+
570+
dynamic "not_principals" {
571+
for_each = try(statement.value.not_principals, [])
572+
573+
content {
574+
type = not_principals.value.type
575+
identifiers = not_principals.value.identifiers
576+
}
577+
}
578+
579+
dynamic "condition" {
580+
for_each = try(statement.value.conditions, [])
581+
582+
content {
583+
test = condition.value.test
584+
values = condition.value.values
585+
variable = condition.value.variable
586+
}
587+
}
588+
}
589+
}
590+
}
591+
592+
resource "aws_iam_role_policy" "this" {
593+
count = local.create_iam_role_policy ? 1 : 0
594+
595+
name = var.iam_role_use_name_prefix ? null : local.iam_role_name
596+
name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null
597+
policy = data.aws_iam_policy_document.role[0].json
598+
role = aws_iam_role.this[0].id
599+
}
600+
538601
################################################################################
539602
# Placement Group
540603
################################################################################

modules/eks-managed-node-group/variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,22 @@ variable "iam_role_tags" {
523523
default = {}
524524
}
525525

526+
################################################################################
527+
# IAM Role Policy
528+
################################################################################
529+
530+
variable "create_iam_role_policy" {
531+
description = "Determines whether an IAM role policy is created or not"
532+
type = bool
533+
default = true
534+
}
535+
536+
variable "iam_role_policy_statements" {
537+
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
538+
type = any
539+
default = []
540+
}
541+
526542
################################################################################
527543
# Autoscaling Group Schedule
528544
################################################################################

modules/fargate-profile/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ No modules.
4747
|------|------|
4848
| [aws_eks_fargate_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_fargate_profile) | resource |
4949
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
50+
| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
5051
| [aws_iam_role_policy_attachment.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
5152
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
5253
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
5354
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
55+
| [aws_iam_policy_document.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
5456
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
5557
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
5658

@@ -62,13 +64,15 @@ No modules.
6264
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `null` | no |
6365
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create Fargate profile or not | `bool` | `true` | no |
6466
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
67+
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
6568
| <a name="input_iam_role_additional_policies"></a> [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `map(string)` | `{}` | no |
6669
| <a name="input_iam_role_arn"></a> [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the Fargate profile. Required if `create_iam_role` is set to `false` | `string` | `null` | no |
6770
| <a name="input_iam_role_attach_cni_policy"></a> [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no |
6871
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no |
6972
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `""` | no |
7073
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
7174
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
75+
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
7276
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no |
7377
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
7478
| <a name="input_name"></a> [name](#input\_name) | Name of the EKS Fargate Profile | `string` | `""` | no |

modules/fargate-profile/main.tf

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,68 @@ resource "aws_iam_role_policy_attachment" "additional" {
7878
role = aws_iam_role.this[0].name
7979
}
8080

81+
################################################################################
82+
# IAM Role Policy
83+
################################################################################
84+
85+
locals {
86+
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && length(var.iam_role_policy_statements) > 0
87+
}
88+
89+
data "aws_iam_policy_document" "role" {
90+
count = local.create_iam_role_policy ? 1 : 0
91+
92+
dynamic "statement" {
93+
for_each = var.iam_role_policy_statements
94+
95+
content {
96+
sid = try(statement.value.sid, null)
97+
actions = try(statement.value.actions, null)
98+
not_actions = try(statement.value.not_actions, null)
99+
effect = try(statement.value.effect, null)
100+
resources = try(statement.value.resources, null)
101+
not_resources = try(statement.value.not_resources, null)
102+
103+
dynamic "principals" {
104+
for_each = try(statement.value.principals, [])
105+
106+
content {
107+
type = principals.value.type
108+
identifiers = principals.value.identifiers
109+
}
110+
}
111+
112+
dynamic "not_principals" {
113+
for_each = try(statement.value.not_principals, [])
114+
115+
content {
116+
type = not_principals.value.type
117+
identifiers = not_principals.value.identifiers
118+
}
119+
}
120+
121+
dynamic "condition" {
122+
for_each = try(statement.value.conditions, [])
123+
124+
content {
125+
test = condition.value.test
126+
values = condition.value.values
127+
variable = condition.value.variable
128+
}
129+
}
130+
}
131+
}
132+
}
133+
134+
resource "aws_iam_role_policy" "this" {
135+
count = local.create_iam_role_policy ? 1 : 0
136+
137+
name = var.iam_role_use_name_prefix ? null : local.iam_role_name
138+
name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null
139+
policy = data.aws_iam_policy_document.role[0].json
140+
role = aws_iam_role.this[0].id
141+
}
142+
81143
################################################################################
82144
# Fargate Profile
83145
################################################################################

modules/fargate-profile/variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@ variable "iam_role_tags" {
8080
default = {}
8181
}
8282

83+
################################################################################
84+
# IAM Role Policy
85+
################################################################################
86+
87+
variable "create_iam_role_policy" {
88+
description = "Determines whether an IAM role policy is created or not"
89+
type = bool
90+
default = true
91+
}
92+
93+
variable "iam_role_policy_statements" {
94+
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
95+
type = any
96+
default = []
97+
}
98+
8399
################################################################################
84100
# Fargate Profile
85101
################################################################################

modules/karpenter/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ No modules.
144144
| <a name="input_iam_policy_description"></a> [iam\_policy\_description](#input\_iam\_policy\_description) | IAM policy description | `string` | `"Karpenter controller IAM policy"` | no |
145145
| <a name="input_iam_policy_name"></a> [iam\_policy\_name](#input\_iam\_policy\_name) | Name of the IAM policy | `string` | `"KarpenterController"` | no |
146146
| <a name="input_iam_policy_path"></a> [iam\_policy\_path](#input\_iam\_policy\_path) | Path of the IAM policy | `string` | `"/"` | no |
147+
| <a name="input_iam_policy_statements"></a> [iam\_policy\_statements](#input\_iam\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
147148
| <a name="input_iam_policy_use_name_prefix"></a> [iam\_policy\_use\_name\_prefix](#input\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`iam_policy_name`) is used as a prefix | `bool` | `true` | no |
148149
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | IAM role description | `string` | `"Karpenter controller IAM role"` | no |
149150
| <a name="input_iam_role_max_session_duration"></a> [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no |

modules/karpenter/main.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,47 @@ data "aws_iam_policy_document" "controller" {
383383
resources = ["arn:${local.partition}:eks:${local.region}:${local.account_id}:cluster/${var.cluster_name}"]
384384
actions = ["eks:DescribeCluster"]
385385
}
386+
387+
dynamic "statement" {
388+
for_each = var.iam_policy_statements
389+
390+
content {
391+
sid = try(statement.value.sid, null)
392+
actions = try(statement.value.actions, null)
393+
not_actions = try(statement.value.not_actions, null)
394+
effect = try(statement.value.effect, null)
395+
resources = try(statement.value.resources, null)
396+
not_resources = try(statement.value.not_resources, null)
397+
398+
dynamic "principals" {
399+
for_each = try(statement.value.principals, [])
400+
401+
content {
402+
type = principals.value.type
403+
identifiers = principals.value.identifiers
404+
}
405+
}
406+
407+
dynamic "not_principals" {
408+
for_each = try(statement.value.not_principals, [])
409+
410+
content {
411+
type = not_principals.value.type
412+
identifiers = not_principals.value.identifiers
413+
}
414+
}
415+
416+
dynamic "condition" {
417+
for_each = try(statement.value.conditions, [])
418+
419+
content {
420+
test = condition.value.test
421+
values = condition.value.values
422+
variable = condition.value.variable
423+
}
424+
}
425+
}
426+
}
386427
}
387428

388429
resource "aws_iam_policy" "controller" {

modules/karpenter/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ variable "iam_policy_description" {
9292
default = "Karpenter controller IAM policy"
9393
}
9494

95+
variable "iam_policy_statements" {
96+
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
97+
type = any
98+
default = []
99+
}
100+
95101
variable "iam_role_policies" {
96102
description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format"
97103
type = map(string)

0 commit comments

Comments
 (0)