From e9141f62c1b4c8ddf9dad20ba5ddc532277a4648 Mon Sep 17 00:00:00 2001 From: David Valentin Date: Tue, 5 Jul 2022 17:18:25 +0200 Subject: [PATCH 1/2] feat: add possibiblity to use AWS IAM roles for service accounts --- README.md | 4 ++++ README.yaml | 3 +++ docs/terraform.md | 3 +++ main.tf | 46 ++++++++++++++++++++++++++++++++++++++++------ variables.tf | 18 ++++++++++++++++++ 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6b74f49..633a274 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,9 @@ Available targets: | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | [iam\_actions](#input\_iam\_actions) | List of actions to allow for the IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost` | `list(string)` | `[]` | no | | [iam\_authorizing\_role\_arns](#input\_iam\_authorizing\_role\_arns) | List of IAM role ARNs to permit to assume the Elasticsearch user role | `list(string)` | `[]` | no | +| [iam\_irsa\_openid\_connect\_provider\_arn](#input\_iam\_irsa\_openid\_connect\_provider\_arn) | ARN of the OpenID connect provider to allow usage of IRSA | `string` | `""` | no | +| [iam\_irsa\_openid\_connect\_provider\_url](#input\_iam\_irsa\_openid\_connect\_provider\_url) | URL of the OpenID connect provider to allow usage of IRSA | `string` | `""` | no | +| [iam\_irsa\_service\_account](#input\_iam\_irsa\_service\_account) | Kubernetes ServiceAccount to allow to access the Elastic Domain via IRSA | `string` | `"system:serviceaccount:default:*"` | no | | [iam\_role\_arns](#input\_iam\_role\_arns) | List of IAM role ARNs to permit access to the Elasticsearch domain | `list(string)` | `[]` | no | | [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) for the user role. Can have a value from 1 hour to 12 hours | `number` | `3600` | no | | [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the permissions boundary policy which will be attached to the Elasticsearch user role | `string` | `null` | no | @@ -317,6 +320,7 @@ For additional context, refer to some of these links. - [Control Access to Amazon Elasticsearch Service Domain](https://aws.amazon.com/blogs/security/how-to-control-access-to-your-amazon-elasticsearch-service-domain/) - Describes how to Control Access to Amazon Elasticsearch Service Domain - [elasticsearch_domain](https://www.terraform.io/docs/providers/aws/r/elasticsearch_domain.html) - Terraform reference documentation for the `elasticsearch_domain` resource - [elasticsearch_domain_policy](https://www.terraform.io/docs/providers/aws/r/elasticsearch_domain_policy.html) - Terraform reference documentation for the `elasticsearch_domain_policy` resource +- [AWS IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) - Associate an IAM role with a Kubernetes service account ## Help diff --git a/README.yaml b/README.yaml index e466e5e..f3a6d86 100644 --- a/README.yaml +++ b/README.yaml @@ -115,6 +115,9 @@ references: - name: "elasticsearch_domain_policy" description: "Terraform reference documentation for the `elasticsearch_domain_policy` resource" url: "https://www.terraform.io/docs/providers/aws/r/elasticsearch_domain_policy.html" + - name: "AWS IAM roles for service accounts" + description: "Associate an IAM role with a Kubernetes service account" + url: "https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html" # Contributors to this project contributors: diff --git a/docs/terraform.md b/docs/terraform.md index 9d0849a..d41bcf9 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -83,6 +83,9 @@ | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | [iam\_actions](#input\_iam\_actions) | List of actions to allow for the IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost` | `list(string)` | `[]` | no | | [iam\_authorizing\_role\_arns](#input\_iam\_authorizing\_role\_arns) | List of IAM role ARNs to permit to assume the Elasticsearch user role | `list(string)` | `[]` | no | +| [iam\_irsa\_openid\_connect\_provider\_arn](#input\_iam\_irsa\_openid\_connect\_provider\_arn) | ARN of the OpenID connect provider to allow usage of IRSA | `string` | `""` | no | +| [iam\_irsa\_openid\_connect\_provider\_url](#input\_iam\_irsa\_openid\_connect\_provider\_url) | URL of the OpenID connect provider to allow usage of IRSA | `string` | `""` | no | +| [iam\_irsa\_service\_account](#input\_iam\_irsa\_service\_account) | Kubernetes ServiceAccount to allow to access the Elastic Domain via IRSA | `string` | `"system:serviceaccount:default:*"` | no | | [iam\_role\_arns](#input\_iam\_role\_arns) | List of IAM role ARNs to permit access to the Elasticsearch domain | `list(string)` | `[]` | no | | [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) for the user role. Can have a value from 1 hour to 12 hours | `number` | `3600` | no | | [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the permissions boundary policy which will be attached to the Elasticsearch user role | `string` | `null` | no | diff --git a/main.tf b/main.tf index f1aa688..4689c9a 100644 --- a/main.tf +++ b/main.tf @@ -82,7 +82,7 @@ resource "aws_iam_role" "elasticsearch_user" { } data "aws_iam_policy_document" "assume_role" { - count = module.this.enabled && (length(var.iam_authorizing_role_arns) > 0 || length(var.iam_role_arns) > 0) ? 1 : 0 + count = module.this.enabled ? 1 : 0 statement { actions = [ @@ -94,12 +94,46 @@ data "aws_iam_policy_document" "assume_role" { identifiers = var.aws_ec2_service_name } - principals { - type = "AWS" - identifiers = compact(concat(var.iam_authorizing_role_arns, var.iam_role_arns)) + effect = "Allow" + } + + dynamic "statement" { + for_each = length(var.iam_authorizing_role_arns) > 0 || length(var.iam_role_arns) > 0 ? [true] : [] + + content { + effect = "Allow" + + actions = [ + "sts:AssumeRole" + ] + + principals { + type = "AWS" + identifiers = compact(concat(var.iam_authorizing_role_arns, var.iam_role_arns)) + } } + } - effect = "Allow" + dynamic "statement" { + for_each = var.iam_irsa_openid_connect_provider_arn != "" ? [true] : [] + content { + effect = "Allow" + + actions = [ + "sts:AssumeRoleWithWebIdentity" + ] + + principals { + type = "Federated" + identifiers = compact([var.iam_irsa_openid_connect_provider_arn]) + } + + condition { + test = "StringLike" + variable = join(":", [var.iam_irsa_openid_connect_provider_url, "sub"]) + values = [var.iam_irsa_service_account] + } + } } } @@ -238,7 +272,7 @@ data "aws_iam_policy_document" "default" { # https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html#es-ac-types-ip # https://aws.amazon.com/premiumsupport/knowledge-center/anonymous-not-authorized-elasticsearch/ dynamic "statement" { - for_each = length(var.allowed_cidr_blocks) > 0 && ! var.vpc_enabled ? [true] : [] + for_each = length(var.allowed_cidr_blocks) > 0 && !var.vpc_enabled ? [true] : [] content { effect = "Allow" diff --git a/variables.tf b/variables.tf index b1dc74d..bd1a6b5 100644 --- a/variables.tf +++ b/variables.tf @@ -106,6 +106,24 @@ variable "iam_actions" { description = "List of actions to allow for the IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost`" } +variable "iam_irsa_openid_connect_provider_arn" { + type = string + default = "" + description = "ARN of the OpenID connect provider to allow usage of IRSA" +} + +variable "iam_irsa_openid_connect_provider_url" { + type = string + default = "" + description = "URL of the OpenID connect provider to allow usage of IRSA" +} + +variable "iam_irsa_service_account" { + type = string + default = "system:serviceaccount:default:*" + description = "Kubernetes ServiceAccount to allow to access the Elastic Domain via IRSA" +} + variable "zone_awareness_enabled" { type = bool default = true From 5a6f9aa974ef5b1d3ec5ed7b8737a15f5057db99 Mon Sep 17 00:00:00 2001 From: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com> Date: Wed, 6 Jul 2022 13:09:57 +0000 Subject: [PATCH 2/2] Auto Format --- .github/renovate.json | 2 +- main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json b/.github/renovate.json index ae4f0aa..a780298 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -4,9 +4,9 @@ ":preserveSemverRanges" ], "labels": ["auto-update"], + "dependencyDashboardAutoclose": true, "enabledManagers": ["terraform"], "terraform": { "ignorePaths": ["**/context.tf", "examples/**"] } } - diff --git a/main.tf b/main.tf index 4689c9a..f7e0329 100644 --- a/main.tf +++ b/main.tf @@ -272,7 +272,7 @@ data "aws_iam_policy_document" "default" { # https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-ac.html#es-ac-types-ip # https://aws.amazon.com/premiumsupport/knowledge-center/anonymous-not-authorized-elasticsearch/ dynamic "statement" { - for_each = length(var.allowed_cidr_blocks) > 0 && !var.vpc_enabled ? [true] : [] + for_each = length(var.allowed_cidr_blocks) > 0 && ! var.vpc_enabled ? [true] : [] content { effect = "Allow"