|
1 | 1 | # iam-eks-role
|
2 | 2 |
|
3 |
| -Creates single IAM role which can be assumed by one or more EKS `ServiceAccount` and optionally also OpenID Connect Federated Users. |
| 3 | +Creates an IAM role that can be assumed by one or more EKS `ServiceAccount` in one or more EKS clusters. Unlike [iam-assumable-role-with-oidc](https://github.com/terraform-aws-modules/terraform-aws-iam/blob/master/modules/iam-assumable-role-with-oidc/), this module: |
| 4 | + |
| 5 | +- Does not require any knowledge of cluster OIDC information as `data` resources are used |
| 6 | +- Supports assuming the role from multiple EKS clusters, for example used in DR or when a workload is spread across clusters |
| 7 | +- Support multiple `ServiceAccount` in the same cluster, for example when a workload runs in multiple namespaces |
| 8 | +- More suitable for non-cluster admins as implementation is simpler |
| 9 | +- More suitable for when the IAM role and cluster resources are in separate Terraform configurations |
4 | 10 |
|
5 | 11 | This module is for use with AWS EKS. For details of how a `ServiceAccount` in EKS can assume an IAM role, see the [EKS documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html).
|
6 | 12 |
|
7 |
| -This module supports multiple `ServiceAccount` in multiple clusters and/or namespaces. This allows for a single IAM role to be used when an application may span multiple clusters (e.g. for DR) or multiple namespaces (e.g. for canary deployments). The variables `cluster_service_accounts` and `provider_url_sa_pairs` are used for this as follows: |
| 13 | +Implementation notes: |
| 14 | + |
| 15 | +- The EKS cluster needs to exist first, in the current AWS account and region |
| 16 | +- The key in the `cluster_service_accounts` is the exact name of the EKS cluster |
| 17 | + |
| 18 | +## Basic example |
| 19 | + |
| 20 | +To create an IAM role named `my-app` that can be assumed in EKS cluster `cluster1` by a `ServiceAccount` called `my-serviceaccount` in the `default` namespace: |
8 | 21 |
|
9 | 22 | ```hcl
|
10 | 23 | module "iam_eks_role" {
|
11 | 24 | source = "terraform-aws-modules/iam/aws//modules/iam-eks-role"
|
12 | 25 |
|
| 26 | + role_name = "my-app" |
| 27 | +
|
13 | 28 | cluster_service_accounts = {
|
14 |
| - "<EKS cluster name>" = [ |
15 |
| - "<namespace>:<ServiceAccount name>", |
16 |
| - "<namespace>:<another ServiceAccount name>" |
17 |
| - ] |
| 29 | + "cluster1" = ["default:my-serviceaccount"] |
18 | 30 | }
|
| 31 | +} |
| 32 | +``` |
19 | 33 |
|
20 |
| - provider_url_sa_pairs = { |
21 |
| - "<OIDC provider without protocol prefix>" = [ |
22 |
| - "<namespace>:<ServiceAccount name>", |
23 |
| - "<namespace>:<another ServiceAccount name>" |
24 |
| - ] |
| 34 | +## Multi cluster example: |
| 35 | + |
| 36 | +To create an IAM role named `my-app` that can be assumed from: |
| 37 | + |
| 38 | +- EKS cluster `staging-main-1`, namespace `default`, `ServiceAccount` called `my-app-staging` |
| 39 | +- EKS cluster `staging-backup-1`, namespace `default`, `ServiceAccount` called `my-app-staging` |
| 40 | + |
| 41 | +```hcl |
| 42 | +module "iam_eks_role" { |
| 43 | + source = "terraform-aws-modules/iam/aws//modules/iam-eks-role" |
| 44 | +
|
| 45 | + role_name = "my-app" |
| 46 | +
|
| 47 | + cluster_service_accounts = { |
| 48 | + "staging-main-1" = ["default:my-app-staging"] |
| 49 | + "staging-backup-1" = ["default:my-app-staging"] |
25 | 50 | }
|
26 | 51 | }
|
27 | 52 | ```
|
28 | 53 |
|
29 |
| -For example, to create an IAM role named `my-app` that can be assumed from the `ServiceAccount` named `my-app-staging` in the namespace `default` and `canary` in EKS cluster named `cluster-main-1`; and also the `ServiceAccount` name `my-app-staging` in the namespace `default` in EKS cluster named `cluster-backup-1`, the configuration would be: |
| 54 | +## Multi `ServiceAccount` example |
| 55 | + |
| 56 | +To create an IAM role named `cloudwatch-exporter` that can be assumed in EKS cluster `production-main-1` from: |
| 57 | + |
| 58 | +- namespace `kube-system`, `ServiceAccount` called `cloudwatch-exporter` |
| 59 | +- namespace `app1`, `ServiceAccount` called `cloudwatch-exporter` |
30 | 60 |
|
31 | 61 | ```hcl
|
32 | 62 | module "iam_eks_role" {
|
33 | 63 | source = "terraform-aws-modules/iam/aws//modules/iam-eks-role"
|
| 64 | +
|
34 | 65 | role_name = "my-app"
|
35 | 66 |
|
36 | 67 | cluster_service_accounts = {
|
37 |
| - "cluster-main-1" = [ |
38 |
| - "default:my-app-staging", |
39 |
| - "canary:my-app-staging" |
40 |
| - ], |
41 |
| - "cluster-backup-1" = [ |
42 |
| - "default:my-app-staging", |
| 68 | + "production-main-1" = [ |
| 69 | + "kube-system:cloudwatch-exporter", |
| 70 | + "app1:cloudwatch-exporter", |
43 | 71 | ]
|
44 | 72 | }
|
45 | 73 | }
|
46 | 74 | ```
|
47 | 75 |
|
48 |
| -Note: the EKS clusters must in the current AWS region and account as they use the default AWS provider. |
49 |
| - |
50 | 76 | <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
51 | 77 | ## Requirements
|
52 | 78 |
|
@@ -84,7 +110,6 @@ No modules.
|
84 | 110 | | <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no |
|
85 | 111 | | <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 |
|
86 | 112 | | <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 |
|
87 |
| -| <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 | |
88 | 113 | | <a name="input_role_description"></a> [role\_description](#input\_role\_description) | IAM Role description | `string` | `""` | no |
|
89 | 114 | | <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name of IAM role | `string` | `null` | no |
|
90 | 115 | | <a name="input_role_name_prefix"></a> [role\_name\_prefix](#input\_role\_name\_prefix) | IAM role name prefix | `string` | `null` | no |
|
|
0 commit comments