Skip to content

Commit bd1a209

Browse files
committed
refactor: update to have users pass in details instead of deriving, this solves dependency issue
1 parent 85fadd0 commit bd1a209

File tree

7 files changed

+207
-101
lines changed

7 files changed

+207
-101
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.62.3
3+
rev: v1.64.0
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_validate

examples/iam-eks-role/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IAM EKS role
22

3-
Configuration in this directory creates an IAM role that can be assumed by multiple EKS `ServiceAccount`.
3+
Configuration in this directory creates IAM roles that can be assumed by multiple EKS `ServiceAccount`s for various tasks.
44

55
# Usage
66

@@ -9,7 +9,6 @@ To run this example you need to execute:
99
```bash
1010
$ terraform init
1111
$ terraform plan
12-
$ terraform apply -target module.vpc -target module.eks
1312
$ terraform apply
1413
```
1514

@@ -33,10 +32,12 @@ No providers.
3332
|------|--------|---------|
3433
| <a name="module_cluster_autoscaler_irsa_role"></a> [cluster\_autoscaler\_irsa\_role](#module\_cluster\_autoscaler\_irsa\_role) | ../../modules/iam-eks-role | n/a |
3534
| <a name="module_ebs_csi_irsa_role"></a> [ebs\_csi\_irsa\_role](#module\_ebs\_csi\_irsa\_role) | ../../modules/iam-eks-role | n/a |
36-
| <a name="module_eks"></a> [eks](#module\_eks) | terraform-aws-modules/eks/aws | ~> 18.0 |
35+
| <a name="module_eks"></a> [eks](#module\_eks) | terraform-aws-modules/eks/aws | ~> 18.6 |
3736
| <a name="module_external_dns_irsa_role"></a> [external\_dns\_irsa\_role](#module\_external\_dns\_irsa\_role) | ../../modules/iam-eks-role | n/a |
3837
| <a name="module_iam_eks_role"></a> [iam\_eks\_role](#module\_iam\_eks\_role) | ../../modules/iam-eks-role | n/a |
3938
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 |
39+
| <a name="module_vpc_cni_ipv4_irsa_role"></a> [vpc\_cni\_ipv4\_irsa\_role](#module\_vpc\_cni\_ipv4\_irsa\_role) | ../../modules/iam-eks-role | n/a |
40+
| <a name="module_vpc_cni_ipv6_irsa_role"></a> [vpc\_cni\_ipv6\_irsa\_role](#module\_vpc\_cni\_ipv6\_irsa\_role) | ../../modules/iam-eks-role | n/a |
4041

4142
## Resources
4243

examples/iam-eks-role/main.tf

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ module "iam_eks_role" {
2323

2424
role_name = local.name
2525

26-
cluster_service_accounts = {
27-
(module.eks.cluster_id) = ["default:my-app", "canary:my-app"]
28-
}
29-
30-
provider_url_sa_pairs = {
31-
"oidc.eks.us-east-1.amazonaws.com/id/5C54DDF35ER19312844C7333374CC09D" = ["default:my-app2"]
32-
"oidc.eks.ap-southeast-1.amazonaws.com/id/5C54DDF35ER54476848E7333374FF09G" = [
33-
"default:my-app2",
34-
"canary:my-app2",
35-
]
26+
oidc_providers = {
27+
one = {
28+
provider = module.eks.oidc_provider
29+
provider_arns = [module.eks.oidc_provider_arn]
30+
service_accounts = ["default:my-app", "canary:my-app"]
31+
}
32+
two = {
33+
provider = module.eks.oidc_provider
34+
provider_arns = [module.eks.oidc_provider_arn]
35+
service_accounts = ["default:blue", "canary:blue"]
36+
}
3637
}
3738

3839
role_policy_arns = [
@@ -48,8 +49,12 @@ module "cluster_autoscaler_irsa_role" {
4849
role_name = "cluster-autoscaler"
4950
attach_cluster_autoscaler_policy = true
5051

51-
cluster_service_accounts = {
52-
(module.eks.cluster_id) = ["default:my-app", "canary:my-app"]
52+
oidc_providers = {
53+
ex = {
54+
provider = module.eks.oidc_provider
55+
provider_arns = [module.eks.oidc_provider_arn]
56+
service_accounts = ["default:my-app", "canary:my-app"]
57+
}
5358
}
5459

5560
tags = local.tags
@@ -62,8 +67,12 @@ module "external_dns_irsa_role" {
6267
attach_external_dns_policy = true
6368
external_dns_hosted_zones = ["IClearlyMadeThisUp"]
6469

65-
cluster_service_accounts = {
66-
(module.eks.cluster_id) = ["default:my-app", "canary:my-app"]
70+
oidc_providers = {
71+
ex = {
72+
provider = module.eks.oidc_provider
73+
provider_arns = [module.eks.oidc_provider_arn]
74+
service_accounts = ["default:my-app", "canary:my-app"]
75+
}
6776
}
6877

6978
tags = local.tags
@@ -75,8 +84,48 @@ module "ebs_csi_irsa_role" {
7584
role_name = "ebs_csi"
7685
attach_ebs_csi_policy = true
7786

78-
cluster_service_accounts = {
79-
(module.eks.cluster_id) = ["default:my-app", "canary:my-app"]
87+
oidc_providers = {
88+
ex = {
89+
provider = module.eks.oidc_provider
90+
provider_arns = [module.eks.oidc_provider_arn]
91+
service_accounts = ["default:my-app", "canary:my-app"]
92+
}
93+
}
94+
95+
tags = local.tags
96+
}
97+
98+
module "vpc_cni_ipv4_irsa_role" {
99+
source = "../../modules/iam-eks-role"
100+
101+
role_name = "vpc_cni_ipv4"
102+
attach_vpc_cni_policy = true
103+
vpc_cni_enable_ipv4 = true
104+
105+
oidc_providers = {
106+
ex = {
107+
provider = module.eks.oidc_provider
108+
provider_arns = [module.eks.oidc_provider_arn]
109+
service_accounts = ["default:my-app", "canary:my-app"]
110+
}
111+
}
112+
113+
tags = local.tags
114+
}
115+
116+
module "vpc_cni_ipv6_irsa_role" {
117+
source = "../../modules/iam-eks-role"
118+
119+
role_name = "vpc_cni_ipv6"
120+
attach_vpc_cni_policy = true
121+
vpc_cni_enable_ipv6 = true
122+
123+
oidc_providers = {
124+
ex = {
125+
provider = module.eks.oidc_provider
126+
provider_arns = [module.eks.oidc_provider_arn]
127+
service_accounts = ["default:my-app", "canary:my-app"]
128+
}
80129
}
81130

82131
tags = local.tags
@@ -120,7 +169,7 @@ module "vpc" {
120169

121170
module "eks" {
122171
source = "terraform-aws-modules/eks/aws"
123-
version = "~> 18.0"
172+
version = "~> 18.6"
124173

125174
cluster_name = local.name
126175
cluster_version = local.cluster_version

modules/iam-eks-role/README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,40 +72,43 @@ No modules.
7272
| [aws_iam_policy.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
7373
| [aws_iam_policy.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
7474
| [aws_iam_policy.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
75+
| [aws_iam_policy.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
7576
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
7677
| [aws_iam_role_policy_attachment.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
7778
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
7879
| [aws_iam_role_policy_attachment.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
7980
| [aws_iam_role_policy_attachment.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
80-
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
81-
| [aws_eks_cluster.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source |
81+
| [aws_iam_role_policy_attachment.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
8282
| [aws_iam_policy_document.assume_role_with_oidc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
8383
| [aws_iam_policy_document.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
8484
| [aws_iam_policy_document.ebs_csi](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
8585
| [aws_iam_policy_document.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
86+
| [aws_iam_policy_document.vpc_cni](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
8687
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
8788

8889
## Inputs
8990

9091
| Name | Description | Type | Default | Required |
9192
|------|-------------|------|---------|:--------:|
92-
| <a name="input_attach_cluster_autoscaler_policy"></a> [attach\_cluster\_autoscaler\_policy](#input\_attach\_cluster\_autoscaler\_policy) | Whether to attach the Cluster Autoscaler IAM policy to the role | `bool` | `false` | no |
93-
| <a name="input_attach_ebs_csi_policy"></a> [attach\_ebs\_csi\_policy](#input\_attach\_ebs\_csi\_policy) | Whether to attach the EBS CSI IAM policy to the role | `bool` | `false` | no |
94-
| <a name="input_attach_external_dns_policy"></a> [attach\_external\_dns\_policy](#input\_attach\_external\_dns\_policy) | Whether to attach the External DNS IAM policy to the role | `bool` | `false` | no |
95-
| <a name="input_cluster_service_accounts"></a> [cluster\_service\_accounts](#input\_cluster\_service\_accounts) | EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details | `map(list(string))` | `{}` | no |
93+
| <a name="input_attach_cluster_autoscaler_policy"></a> [attach\_cluster\_autoscaler\_policy](#input\_attach\_cluster\_autoscaler\_policy) | Determines whether to attach the Cluster Autoscaler IAM policy to the role | `bool` | `false` | no |
94+
| <a name="input_attach_ebs_csi_policy"></a> [attach\_ebs\_csi\_policy](#input\_attach\_ebs\_csi\_policy) | Determines whether to attach the EBS CSI IAM policy to the role | `bool` | `false` | no |
95+
| <a name="input_attach_external_dns_policy"></a> [attach\_external\_dns\_policy](#input\_attach\_external\_dns\_policy) | Determines whether to attach the External DNS IAM policy to the role | `bool` | `false` | no |
96+
| <a name="input_attach_vpc_cni_policy"></a> [attach\_vpc\_cni\_policy](#input\_attach\_vpc\_cni\_policy) | Determines whether to attach the VPC CNI IAM policy to the role | `bool` | `false` | no |
9697
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no |
9798
| <a name="input_ebs_csi_kms_cmk_ids"></a> [ebs\_csi\_kms\_cmk\_ids](#input\_ebs\_csi\_kms\_cmk\_ids) | KMS CMK IDs to allow EBS CSI to manage encrypted volumes | `list(string)` | `[]` | no |
9899
| <a name="input_external_dns_hosted_zones"></a> [external\_dns\_hosted\_zones](#input\_external\_dns\_hosted\_zones) | Route53 hosted zone IDs to allow external DNS to manage records | `list(string)` | <pre>[<br> "*"<br>]</pre> | no |
99-
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
100-
| <a name="input_max_session_duration"></a> [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `43200` | no |
101-
| <a name="input_provider_url_sa_pairs"></a> [provider\_url\_sa\_pairs](#input\_provider\_url\_sa\_pairs) | OIDC provider URL and k8s ServiceAccount pairs. If the assume role policy requires a mix of EKS clusters and other OIDC providers then this can be used | `map(list(string))` | `{}` | no |
102-
| <a name="input_role_description"></a> [role\_description](#input\_role\_description) | IAM Role description | `string` | `""` | no |
100+
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `true` | no |
101+
| <a name="input_max_session_duration"></a> [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `null` | no |
102+
| <a name="input_oidc_providers"></a> [oidc\_providers](#input\_oidc\_providers) | Map of OIDC providers where each provdier map should contain the `provider`, `provider_arns`, and `service_accounts` | `any` | `{}` | no |
103+
| <a name="input_role_description"></a> [role\_description](#input\_role\_description) | IAM Role description | `string` | `null` | no |
103104
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name of IAM role | `string` | `null` | no |
104105
| <a name="input_role_name_prefix"></a> [role\_name\_prefix](#input\_role\_name\_prefix) | IAM role name prefix | `string` | `null` | no |
105-
| <a name="input_role_path"></a> [role\_path](#input\_role\_path) | Path of IAM role | `string` | `"/"` | no |
106-
| <a name="input_role_permissions_boundary_arn"></a> [role\_permissions\_boundary\_arn](#input\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role | `string` | `""` | no |
106+
| <a name="input_role_path"></a> [role\_path](#input\_role\_path) | Path of IAM role | `string` | `null` | no |
107+
| <a name="input_role_permissions_boundary_arn"></a> [role\_permissions\_boundary\_arn](#input\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role | `string` | `null` | no |
107108
| <a name="input_role_policy_arns"></a> [role\_policy\_arns](#input\_role\_policy\_arns) | ARNs of any policies to attach to the IAM role | `list(string)` | `[]` | no |
108109
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add the the IAM role | `map(any)` | `{}` | no |
110+
| <a name="input_vpc_cni_enable_ipv4"></a> [vpc\_cni\_enable\_ipv4](#input\_vpc\_cni\_enable\_ipv4) | Determines whether to enable IPv4 permissions for VPC CNI policy | `bool` | `false` | no |
111+
| <a name="input_vpc_cni_enable_ipv6"></a> [vpc\_cni\_enable\_ipv6](#input\_vpc\_cni\_enable\_ipv6) | Determines whether to enable IPv6 permissions for VPC CNI policy | `bool` | `false` | no |
109112

110113
## Outputs
111114

modules/iam-eks-role/main.tf

Lines changed: 15 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,22 @@
1-
data "aws_caller_identity" "current" {}
2-
3-
data "aws_partition" "current" {}
4-
5-
data "aws_eks_cluster" "main" {
6-
for_each = var.cluster_service_accounts
7-
8-
name = each.key
9-
}
10-
111
data "aws_iam_policy_document" "assume_role_with_oidc" {
12-
dynamic "statement" {
13-
for_each = var.cluster_service_accounts
14-
15-
content {
16-
effect = "Allow"
17-
actions = ["sts:AssumeRoleWithWebIdentity"]
18-
19-
principals {
20-
type = "Federated"
21-
22-
identifiers = [
23-
"arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${replace(data.aws_eks_cluster.main[statement.key].identity[0].oidc[0].issuer, "https://", "")}"
24-
]
25-
}
26-
27-
condition {
28-
test = "StringEquals"
29-
variable = "${replace(data.aws_eks_cluster.main[statement.key].identity[0].oidc[0].issuer, "https://", "")}:sub"
30-
values = [for s in statement.value : "system:serviceaccount:${s}"]
31-
}
32-
}
33-
}
2+
count = var.create_role ? 1 : 0
343

354
dynamic "statement" {
36-
for_each = var.provider_url_sa_pairs
5+
for_each = var.oidc_providers
376

387
content {
398
effect = "Allow"
409
actions = ["sts:AssumeRoleWithWebIdentity"]
4110

4211
principals {
43-
type = "Federated"
44-
45-
identifiers = [
46-
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${statement.key}"
47-
]
12+
type = "Federated"
13+
identifiers = statement.value.provider_arns
4814
}
4915

5016
condition {
5117
test = "StringEquals"
52-
variable = "${statement.key}:sub"
53-
values = [for s in statement.value : "system:serviceaccount:${s}"]
18+
variable = "${statement.value.provider}:sub"
19+
values = [for sa in statement.value.service_accounts : "system:serviceaccount:${sa}"]
5420
}
5521
}
5622
}
@@ -59,15 +25,17 @@ data "aws_iam_policy_document" "assume_role_with_oidc" {
5925
resource "aws_iam_role" "this" {
6026
count = var.create_role ? 1 : 0
6127

62-
assume_role_policy = data.aws_iam_policy_document.assume_role_with_oidc.json
63-
description = var.role_description
64-
force_detach_policies = var.force_detach_policies
28+
name = var.role_name
29+
name_prefix = var.role_name_prefix
30+
path = var.role_path
31+
description = var.role_description
32+
33+
assume_role_policy = data.aws_iam_policy_document.assume_role_with_oidc[0].json
6534
max_session_duration = var.max_session_duration
66-
name = var.role_name
67-
name_prefix = var.role_name_prefix
68-
path = var.role_path
6935
permissions_boundary = var.role_permissions_boundary_arn
70-
tags = var.tags
36+
force_detach_policies = var.force_detach_policies
37+
38+
tags = var.tags
7139
}
7240

7341
resource "aws_iam_role_policy_attachment" "custom" {

0 commit comments

Comments
 (0)