Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IRSA module refactor (No Breaking changes) #832

Merged
merged 11 commits into from
Aug 9, 2022
30 changes: 27 additions & 3 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ data "aws_eks_cluster_auth" "this" {

### `exec()` Example

Usage of exec plugin for AWS credentials

Links to References related to this issue

- https://github.com/hashicorp/terraform/issues/29182
- https://github.com/aws/aws-cli/pull/6476

```hcl
provider "kubernetes" {
host = module.eks_blueprints.eks_cluster_endpoint
Expand Down Expand Up @@ -114,7 +121,24 @@ provider "kubectl" {
}
```

### References
### How to use IRSA module

- https://github.com/hashicorp/terraform/issues/29182
- https://github.com/aws/aws-cli/pull/6476
Sample code snippet for using IRSA module directly

```hcl

locals {
eks_oidc_issuer_url = "<ENTER_OIDC_ISSUER_URL>" # e.g., "oidc.eks.eu-west-1.amazonaws.com/id/E6CAB5CSOMEUNIQUEID55B9D01F7"
}

module "irsa" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/irsa"
kubernetes_namespace = "dev"
kubernetes_service_account = "spark"
irsa_iam_policies = ["<ENTER_IAM_POLICY_ARN>"]
eks_cluster_id = "my-test-cluster"
eks_oidc_provider_arn = "arn:aws:iam::<YOUR_ACCOUNT_ID>:oidc-provider/${local.eks_oidc_issuer_url}"
eks_oidc_issuer_url = local.eks_oidc_issuer_url
}

```
8 changes: 7 additions & 1 deletion modules/irsa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,18 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_addon_context"></a> [addon\_context](#input\_addon\_context) | Input configuration for the addon | <pre>object({<br> aws_caller_identity_account_id = string<br> aws_caller_identity_arn = string<br> aws_eks_cluster_endpoint = string<br> aws_partition_id = string<br> aws_region_name = string<br> eks_cluster_id = string<br> eks_oidc_issuer_url = string<br> eks_oidc_provider_arn = string<br> tags = map(string)<br> irsa_iam_role_name = optional(string)<br> irsa_iam_role_path = optional(string)<br> irsa_iam_permissions_boundary = optional(string)<br> })</pre> | n/a | yes |
| <a name="input_create_kubernetes_namespace"></a> [create\_kubernetes\_namespace](#input\_create\_kubernetes\_namespace) | Should the module create the namespace | `bool` | `true` | no |
| <a name="input_create_kubernetes_service_account"></a> [create\_kubernetes\_service\_account](#input\_create\_kubernetes\_service\_account) | Should the module create the Service Account | `bool` | `true` | no |
| <a name="input_eks_cluster_id"></a> [eks\_cluster\_id](#input\_eks\_cluster\_id) | EKS Cluster ID | `string` | n/a | yes |
| <a name="input_eks_oidc_issuer_url"></a> [eks\_oidc\_issuer\_url](#input\_eks\_oidc\_issuer\_url) | The OpenID Connect identity provider (issuer URL without leading `https://`) | `string` | n/a | yes |
| <a name="input_eks_oidc_provider_arn"></a> [eks\_oidc\_provider\_arn](#input\_eks\_oidc\_provider\_arn) | EKS OIDC Provider ARN e.g., arn:aws:iam::<ACCOUNT-ID>:oidc-provider/<var.eks\_oidc\_provider> | `string` | n/a | yes |
| <a name="input_irsa_iam_permissions_boundary"></a> [irsa\_iam\_permissions\_boundary](#input\_irsa\_iam\_permissions\_boundary) | IAM permissions boundary for IRSA roles | `string` | `""` | no |
| <a name="input_irsa_iam_policies"></a> [irsa\_iam\_policies](#input\_irsa\_iam\_policies) | IAM Policies for IRSA IAM role | `list(string)` | `[]` | no |
| <a name="input_irsa_iam_role_name"></a> [irsa\_iam\_role\_name](#input\_irsa\_iam\_role\_name) | IAM role name for IRSA | `string` | `""` | no |
| <a name="input_irsa_iam_role_path"></a> [irsa\_iam\_role\_path](#input\_irsa\_iam\_role\_path) | IAM role path for IRSA roles | `string` | `"/"` | no |
| <a name="input_kubernetes_namespace"></a> [kubernetes\_namespace](#input\_kubernetes\_namespace) | Kubernetes Namespace name | `string` | n/a | yes |
| <a name="input_kubernetes_service_account"></a> [kubernetes\_service\_account](#input\_kubernetes\_service\_account) | Kubernetes Service Account Name | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit`,`XYZ`) | `map(string)` | `{}` | no |

## Outputs

Expand Down
14 changes: 7 additions & 7 deletions modules/irsa/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,31 @@ resource "kubernetes_service_account_v1" "irsa" {
resource "aws_iam_role" "irsa" {
count = var.irsa_iam_policies != null ? 1 : 0

name = try(coalesce(var.addon_context.irsa_iam_role_name, format("%s-%s-%s", var.addon_context.eks_cluster_id, trim(var.kubernetes_service_account, "-*"), "irsa")), null)
name = try(coalesce(var.irsa_iam_role_name, format("%s-%s-%s", var.eks_cluster_id, trim(var.kubernetes_service_account, "-*"), "irsa")), null)
description = "AWS IAM Role for the Kubernetes service account ${var.kubernetes_service_account}."
assume_role_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Federated" : "${var.addon_context.eks_oidc_provider_arn}"
"Federated" : "${var.eks_oidc_provider_arn}"
},
"Action" : "sts:AssumeRoleWithWebIdentity",
"Condition" : {
"StringLike" : {
"${var.addon_context.eks_oidc_issuer_url}:sub" : "system:serviceaccount:${var.kubernetes_namespace}:${var.kubernetes_service_account}",
"${var.addon_context.eks_oidc_issuer_url}:aud" : "sts.amazonaws.com"
"${var.eks_oidc_issuer_url}:sub" : "system:serviceaccount:${var.kubernetes_namespace}:${var.kubernetes_service_account}",
vara-bonthu marked this conversation as resolved.
Show resolved Hide resolved
"${var.eks_oidc_issuer_url}:aud" : "sts.amazonaws.com"
}
}
}
]
})
path = var.addon_context.irsa_iam_role_path
path = var.irsa_iam_role_path
force_detach_policies = true
permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
permissions_boundary = var.irsa_iam_permissions_boundary

tags = var.addon_context.tags
tags = var.tags
}

resource "aws_iam_role_policy_attachment" "irsa" {
Expand Down
53 changes: 37 additions & 16 deletions modules/irsa/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,41 @@ variable "irsa_iam_policies" {
default = []
}

variable "addon_context" {
description = "Input configuration for the addon"
type = object({
aws_caller_identity_account_id = string
aws_caller_identity_arn = string
aws_eks_cluster_endpoint = string
aws_partition_id = string
aws_region_name = string
eks_cluster_id = string
eks_oidc_issuer_url = string
eks_oidc_provider_arn = string
tags = map(string)
irsa_iam_role_name = optional(string)
irsa_iam_role_path = optional(string)
irsa_iam_permissions_boundary = optional(string)
})
variable "irsa_iam_role_name" {
type = string
description = "IAM role name for IRSA"
default = ""
}

variable "irsa_iam_role_path" {
description = "IAM role path for IRSA roles"
type = string
default = "/"
}

variable "irsa_iam_permissions_boundary" {
description = "IAM permissions boundary for IRSA roles"
type = string
default = ""
}

variable "eks_oidc_issuer_url" {
description = "The OpenID Connect identity provider (issuer URL without leading `https://`)"
type = string
}

variable "eks_oidc_provider_arn" {
description = "EKS OIDC Provider ARN e.g., arn:aws:iam::<ACCOUNT-ID>:oidc-provider/<var.eks_oidc_provider>"
type = string
}

variable "eks_cluster_id" {
description = "EKS Cluster ID"
type = string
}

variable "tags" {
description = "Additional tags (e.g. `map('BusinessUnit`,`XYZ`)"
type = map(string)
default = {}
}
6 changes: 5 additions & 1 deletion modules/kubernetes-addons/aws-ebs-csi-driver/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ module "irsa_addon" {
kubernetes_namespace = "kube-system"
kubernetes_service_account = "ebs-csi-controller-sa"
irsa_iam_policies = concat([aws_iam_policy.aws_ebs_csi_driver[0].arn], try(var.addon_config.additional_iam_policies, []))
addon_context = var.addon_context
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
}

resource "aws_iam_policy" "aws_ebs_csi_driver" {
Expand Down
6 changes: 5 additions & 1 deletion modules/kubernetes-addons/aws-vpc-cni/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ module "irsa_addon" {
create_kubernetes_service_account = false
kubernetes_namespace = "kube-system"
kubernetes_service_account = "aws-node"
addon_context = var.addon_context
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
irsa_iam_policies = concat(
["arn:${var.addon_context.aws_partition_id}:iam::aws:policy/AmazonEKS_CNI_Policy"],
local.cni_ipv6_policy,
Expand Down
18 changes: 12 additions & 6 deletions modules/kubernetes-addons/crossplane/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ module "aws_provider_irsa" {
kubernetes_namespace = local.namespace
kubernetes_service_account = "${local.aws_provider_sa}-*"
irsa_iam_policies = concat([aws_iam_policy.aws_provider[0].arn], var.aws_provider.additional_irsa_policies)
addon_context = var.addon_context

depends_on = [kubectl_manifest.aws_provider]
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
depends_on = [kubectl_manifest.aws_provider]
}

resource "aws_iam_policy" "aws_provider" {
Expand Down Expand Up @@ -102,9 +105,12 @@ module "jet_aws_provider_irsa" {
kubernetes_namespace = local.namespace
kubernetes_service_account = "${local.jet_aws_provider_sa}-*"
irsa_iam_policies = concat([aws_iam_policy.jet_aws_provider[0].arn], var.jet_aws_provider.additional_irsa_policies)
addon_context = var.addon_context

depends_on = [kubectl_manifest.jet_aws_provider]
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
depends_on = [kubectl_manifest.jet_aws_provider]
}

resource "aws_iam_policy" "jet_aws_provider" {
Expand Down
1 change: 1 addition & 0 deletions modules/kubernetes-addons/helm-addon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Helm Addon module can be used to provision a generic Helm Chart as an Add-On for
| <a name="input_addon_context"></a> [addon\_context](#input\_addon\_context) | Input configuration for the addon | <pre>object({<br> aws_caller_identity_account_id = string<br> aws_caller_identity_arn = string<br> aws_eks_cluster_endpoint = string<br> aws_partition_id = string<br> aws_region_name = string<br> eks_cluster_id = string<br> eks_oidc_issuer_url = string<br> eks_oidc_provider_arn = string<br> tags = map(string)<br> irsa_iam_role_path = optional(string)<br> irsa_iam_permissions_boundary = optional(string)<br> })</pre> | n/a | yes |
| <a name="input_helm_config"></a> [helm\_config](#input\_helm\_config) | Helm chart config. Repository and version required. See https://registry.terraform.io/providers/hashicorp/helm/latest/docs | `any` | n/a | yes |
| <a name="input_irsa_config"></a> [irsa\_config](#input\_irsa\_config) | Input configuration for IRSA module | <pre>object({<br> kubernetes_namespace = string<br> create_kubernetes_namespace = optional(bool)<br> kubernetes_service_account = string<br> create_kubernetes_service_account = optional(bool)<br> irsa_iam_policies = optional(list(string))<br> })</pre> | `null` | no |
| <a name="input_irsa_iam_role_name"></a> [irsa\_iam\_role\_name](#input\_irsa\_iam\_role\_name) | IAM role name for IRSA | `string` | `""` | no |
| <a name="input_manage_via_gitops"></a> [manage\_via\_gitops](#input\_manage\_via\_gitops) | Determines if the add-on should be managed via GitOps | `bool` | `false` | no |
| <a name="input_set_sensitive_values"></a> [set\_sensitive\_values](#input\_set\_sensitive\_values) | Forced set\_sensitive values | `any` | `[]` | no |
| <a name="input_set_values"></a> [set\_values](#input\_set\_values) | Forced set values | `any` | `[]` | no |
Expand Down
7 changes: 6 additions & 1 deletion modules/kubernetes-addons/helm-addon/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,10 @@ module "irsa" {
kubernetes_namespace = var.irsa_config.kubernetes_namespace
kubernetes_service_account = var.irsa_config.kubernetes_service_account
irsa_iam_policies = var.irsa_config.irsa_iam_policies
addon_context = var.addon_context
irsa_iam_role_name = var.irsa_iam_role_name
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
}
6 changes: 6 additions & 0 deletions modules/kubernetes-addons/helm-addon/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ variable "manage_via_gitops" {
default = false
}

variable "irsa_iam_role_name" {
type = string
description = "IAM role name for IRSA"
default = ""
}

variable "irsa_config" {
description = "Input configuration for IRSA module"
type = object({
Expand Down
20 changes: 14 additions & 6 deletions modules/kubernetes-addons/prometheus/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,13 @@ module "irsa_amp_ingest" {
create_kubernetes_namespace = false
kubernetes_namespace = local.namespace

kubernetes_service_account = local.ingest_service_account
irsa_iam_policies = [aws_iam_policy.ingest[0].arn]
addon_context = var.addon_context
kubernetes_service_account = local.ingest_service_account
irsa_iam_policies = [aws_iam_policy.ingest[0].arn]
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
}

# ------------------------------------------
Expand Down Expand Up @@ -148,7 +152,11 @@ module "irsa_amp_query" {
create_kubernetes_namespace = false
kubernetes_namespace = local.namespace

kubernetes_service_account = "amp-query"
irsa_iam_policies = [aws_iam_policy.query[0].arn]
addon_context = var.addon_context
kubernetes_service_account = "amp-query"
irsa_iam_policies = [aws_iam_policy.query[0].arn]
irsa_iam_role_path = var.addon_context.irsa_iam_role_path
irsa_iam_permissions_boundary = var.addon_context.irsa_iam_permissions_boundary
eks_cluster_id = var.addon_context.eks_cluster_id
eks_oidc_provider_arn = var.addon_context.eks_oidc_provider_arn
eks_oidc_issuer_url = var.addon_context.eks_oidc_issuer_url
}