diff --git a/README.md b/README.md index 6b442674..569c7d0e 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ module "opensearch_domain" { domain_name = "my-opensearch-domain" subnet_ids = module.eks_cluster.private_subnet_ids - security_group_ids = module.eks_cluster.security_group_ids vpc_id = module.eks_cluster.vpc_id cidr_blocks = concat(module.eks_cluster.private_vpc_cidr_blocks, module.eks_cluster.public_vpc_cidr_blocks) @@ -74,6 +73,34 @@ module "opensearch_domain" { } ``` +#### Deletion Known Issues + +During the deletion process (`terraform destroy`) of the EKS Cluster, you may encounter an error message related to the `kubernetes_storage_class`: + +```` +Error: Get "http://localhost/apis/storage.k8s.io/v1/storageclasses/ebs-sc": dial tcp [::1]:80: connect: connection refused +│ +│ with module.eks_cluster.kubernetes_storage_class_v1.ebs_sc, +│ on .terraform/modules/eks_cluster/modules/eks-cluster/cluster.tf line 156, in resource "kubernetes_storage_class_v1" "ebs_sc": +│ 156: resource "kubernetes_storage_class_v1" "ebs_sc" { +│ +╵ +```` + +To resolve this issue, you can set the variable `create_ebs_gp3_default_storage_class` to `false`, which skips the creation of the `kubernetes_storage_class` resource. This helps to avoid dependency issues during deletion. Run the following command: + +```bash +terraform destroy -var="create_ebs_gp3_default_storage_class=false" +``` + +If you still encounter the issue, you may need to manually remove the state for the storage class: + +```bash +terraform state rm module.eks_cluster.kubernetes_storage_class_v1.ebs_sc +``` + +After performing these steps, re-run `terraform destroy` to complete the deletion process without further interruptions. + #### GitHub Actions You can automate the deployment and deletion of the EKS cluster and Aurora database using GitHub Actions. @@ -102,8 +129,7 @@ The Aurora module uses the following outputs from the EKS cluster module to defi - `module.eks_cluster.oidc_provider_arn`: The ARN of the OIDC provider for the EKS cluster. - `module.eks_cluster.oidc_provider_id`: The ID of the OIDC provider for the EKS cluster. - `var.account_id`: Your AWS account id -- `var.aurora_cluster_name`: The name of the Aurora cluster to access -Here is the corrected version: +- `var.aurora_region`: Your Aurora AWS Region - `var.aurora_irsa_username`: The username used to access AuroraDB. This username is different from the superuser. The user must also be created manually in the database to enable the IRSA connection, as described in [the steps below](#create-irsa-user-on-the-database). - `var.aurora_namespace`: The kubernetes namespace to allow access - `var.aurora_service_account`: The kubernetes ServiceAccount to allow access @@ -113,7 +139,15 @@ You need to define the IAM role trust policy and access policy for Aurora. Here' ```hcl module "postgresql" { # ... - iam_aurora_access_policy = <:role/AuroraRole> ``` -You can retrieve the role ARN from the module output: `aurora_role_arn`. +You can retrieve the role ARN from the module output: `aurora_iam_role_arns['Aurora-your-cluster']`. **OpenSearch Service Account** @@ -258,7 +296,7 @@ metadata: annotations: eks.amazonaws.com/role-arn: :role/OpenSearchRole> ``` -You can retrieve the role ARN from the module output: `opensearch_role_arn`. +You can retrieve the role ARN from the module output: `opensearch_iam_role_arns['OpenSearch-your-cluster']`. ## Support diff --git a/examples/camunda-8.6-irsa/README.md b/examples/camunda-8.6-irsa/README.md new file mode 100644 index 00000000..4ca0d850 --- /dev/null +++ b/examples/camunda-8.6-irsa/README.md @@ -0,0 +1,4 @@ +# Camunda 8.6 on AWS EKS with IRSA + +This folder describes the IaC of Camunda 8.6 on AWS EKS with IRSA. +Instructions can be found on the official documentation: https://docs.camunda.io/docs/self-managed/setup/deploy/amazon/amazon-eks/eks-terraform/ diff --git a/examples/camunda-8.6-irsa/cluster.tf b/examples/camunda-8.6-irsa/cluster.tf new file mode 100644 index 00000000..4a0c7a9b --- /dev/null +++ b/examples/camunda-8.6-irsa/cluster.tf @@ -0,0 +1,29 @@ +locals { + eks_cluster_name = "cluster-name-irsa" # Change this to a name of your choice + eks_cluster_region = "eu-west-2" # Change this to your desired AWS region +} + +module "eks_cluster" { + source = "git::https://github.com/camunda/camunda-tf-eks-module//modules/eks-cluster?ref=3.0.0" + + name = local.eks_cluster_name + region = local.eks_cluster_region + + # Set CIDR ranges or use the defaults + cluster_service_ipv4_cidr = "10.190.0.0/16" + cluster_node_ipv4_cidr = "10.192.0.0/16" + + # Default node type for the Kubernetes cluster + np_instance_types = ["m6i.xlarge"] + np_desired_node_count = 4 +} + +output "cert_manager_arn" { + value = module.eks_cluster.cert_manager_arn + description = "The Amazon Resource Name (ARN) of the AWS IAM Roles for Service Account mapping for the cert-manager" +} + +output "external_dns_arn" { + value = module.eks_cluster.external_dns_arn + description = "The Amazon Resource Name (ARN) of the AWS IAM Roles for Service Account mapping for the external-dns" +} diff --git a/examples/camunda-8.6-irsa/config.tf b/examples/camunda-8.6-irsa/config.tf new file mode 100644 index 00000000..16a100dc --- /dev/null +++ b/examples/camunda-8.6-irsa/config.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">= 1.0" + + # You can override the backend configuration; this is given as an example. + backend "s3" { + encrypt = true + } + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.69" + } + } +} + +provider "aws" {} diff --git a/examples/camunda-8.6-irsa/db.tf b/examples/camunda-8.6-irsa/db.tf new file mode 100644 index 00000000..c878f6f6 --- /dev/null +++ b/examples/camunda-8.6-irsa/db.tf @@ -0,0 +1,181 @@ +locals { + aurora_cluster_name = "cluster-name-pg-irsa" # Replace "cluster-name" with your cluster's name + + aurora_master_username = "secret_user" # Replace with your Aurora username + aurora_master_password = "secretvalue%23" # Replace with your Aurora password, password must contain at least one letter, one number, and one special character. + + + camunda_database_keycloak = "camunda_keycloak" # Name of your camunda database for Keycloak + camunda_database_identity = "camunda_identity" # Name of your camunda database for Identity + camunda_database_webmodeler = "camunda_webmodeler" # Name of your camunda database for WebModeler + + # IRSA configuration + camunda_keycloak_db_username = "keycloak_irsa" # This is the username that will be used for IRSA connection to the DB on Keycloak db + camunda_identity_db_username = "identity_irsa" # This is the username that will be used for IRSA connection to the DB on Identity db + camunda_webmodeler_db_username = "webmodeler_irsa" # This is the username that will be used for IRSA connection to the DB on WebModeler db + + camunda_keycloak_service_account = "keycloak-sa" # Replace with your Kubernetes ServiceAcccount that will be created for Keycloak + camunda_identity_service_account = "identity-sa" # Replace with your Kubernetes ServiceAcccount that will be created for Identity + camunda_webmodeler_service_account = "webmodeler-sa" # Replace with your Kubernetes ServiceAcccount that will be created for WebModeler + + camunda_keycloak_role_name = "AuroraRole-Keycloak-${local.aurora_cluster_name}" # IAM Role name use to allow access to the keycloak db + camunda_identity_role_name = "AuroraRole-Identity-${local.aurora_cluster_name}" # IAM Role name use to allow access to the identity db + camunda_webmodeler_role_name = "AuroraRole-Webmodeler-${local.aurora_cluster_name}" # IAM Role name use to allow access to the webmodeler db +} + +module "postgresql" { + source = "git::https://github.com/camunda/camunda-tf-eks-module//modules/aurora?ref=3.0.0" + engine_version = "15.8" + auto_minor_version_upgrade = false + cluster_name = local.aurora_cluster_name + default_database_name = local.camunda_database_keycloak + + availability_zones = ["${local.eks_cluster_region}a", "${local.eks_cluster_region}b", "${local.eks_cluster_region}c"] + + username = local.aurora_master_username + password = local.aurora_master_password + + vpc_id = module.eks_cluster.vpc_id + subnet_ids = module.eks_cluster.private_subnet_ids + cidr_blocks = concat(module.eks_cluster.private_vpc_cidr_blocks, module.eks_cluster.public_vpc_cidr_blocks) + + num_instances = "1" # only one instance, you can add add other read-only instances if you want + instance_class = "db.t3.medium" + + # IAM IRSA + iam_auth_enabled = true + iam_roles_with_policies = [ + { + role_name = local.camunda_keycloak_role_name + trust_policy = < [default\_database\_name](#input\_default\_database\_name) | The name for the automatically created database on cluster creation. | `string` | `"camunda"` | no | | [engine](#input\_engine) | The engine type e.g. aurora, aurora-mysql, aurora-postgresql, ... | `string` | `"aurora-postgresql"` | no | | [engine\_version](#input\_engine\_version) | The DB engine version for Postgres to use. | `string` | `"15.4"` | no | -| [iam\_aurora\_access\_policy](#input\_iam\_aurora\_access\_policy) | Access policy for Aurora allowing access | `string` | `" {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"rds-db:connect\"\n ],\n \"Resource\": \"arn:aws:rds-db:::dbuser:/\"\n }\n ]\n }\n\n"` | no | -| [iam\_aurora\_role\_name](#input\_iam\_aurora\_role\_name) | Name of the AuroraRole IAM role | `string` | `"AuroraRole"` | no | | [iam\_auth\_enabled](#input\_iam\_auth\_enabled) | Determines whether IAM auth should be activated for IRSA usage | `bool` | `false` | no | -| [iam\_create\_aurora\_role](#input\_iam\_create\_aurora\_role) | Flag to determine if the Aurora IAM role should be created, if true, this module will create a role. Please ensure that iam\_auth\_enabled is set to `true` | `bool` | `false` | no | -| [iam\_role\_trust\_policy](#input\_iam\_role\_trust\_policy) | Assume role trust policy for Aurora role | `string` | `" {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Federated\": \"arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Condition\": {\n \"StringEquals\": {\n \"oidc.eks..amazonaws.com/id/:sub\": \"system:serviceaccount::\"\n }\n }\n }\n ]\n }\n\n"` | no | | [iam\_roles](#input\_iam\_roles) | Allows propagating additional IAM roles to the Aurora cluster to allow e.g. access to S3 | `list(string)` | `[]` | no | +| [iam\_roles\_with\_policies](#input\_iam\_roles\_with\_policies) | List of roles with their trust and access policies |
list(object({
# Name of the Role to create
role_name = string

# Assume role trust policy for this Aurora role as a json string
trust_policy = string

# Access policy for Aurora allowing access as a json string
# see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html
# Since the DbiResourceId may be unknown during the apply process, and because each instance of the RDS cluster contains its own DbiResourceId,
# we use the wildcard `dbuser:*` to apply to all database instances.
# Example:
# [
# {
# role_name = "AuroraRole"
# trust_policy =
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "Principal": {
# "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/"
# },
# "Action": "sts:AssumeRoleWithWebIdentity",
# "Condition": {
# "StringEquals": {
# "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::"
# }
# }
# }
# ]
# }
#
# access_policy =
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "Action": [
# "rds-db:connect"
# ],
# "Resource": "arn:aws:rds-db:::dbuser:*/"
# }
# ]
# }
#
# }
# ]
access_policy = string
}))
| `[]` | no | | [instance\_class](#input\_instance\_class) | The instance type of the Aurora instances | `string` | `"db.t3.medium"` | no | | [num\_instances](#input\_num\_instances) | Number of instances | `string` | `"1"` | no | | [password](#input\_password) | The password for the postgres admin user. Important: secret value! | `string` | n/a | yes | @@ -74,8 +71,10 @@ No modules. | Name | Description | |------|-------------| +| [aurora\_cluster\_identifier](#output\_aurora\_cluster\_identifier) | RDS Cluster Identifier | +| [aurora\_cluster\_resource\_id](#output\_aurora\_cluster\_resource\_id) | RDS Cluster Resource ID | | [aurora\_endpoint](#output\_aurora\_endpoint) | The endpoint of the Aurora cluster | -| [aurora\_policy\_arn](#output\_aurora\_policy\_arn) | The ARN of the aurora access policy | -| [aurora\_role\_arn](#output\_aurora\_role\_arn) | The ARN of the aurora IAM role | -| [aurora\_role\_name](#output\_aurora\_role\_name) | The name of the aurora IAM role | +| [aurora\_iam\_role\_access\_policy\_arns](#output\_aurora\_iam\_role\_access\_policy\_arns) | Map of IAM role names to their access policy ARNs | +| [aurora\_iam\_role\_arns](#output\_aurora\_iam\_role\_arns) | Map of IAM role names to their ARNs | +| [aurora\_id](#output\_aurora\_id) | RDS Cluster Identifier | diff --git a/modules/aurora/output.tf b/modules/aurora/output.tf deleted file mode 100644 index 0457cd94..00000000 --- a/modules/aurora/output.tf +++ /dev/null @@ -1,22 +0,0 @@ -output "aurora_endpoint" { - value = aws_rds_cluster.aurora_cluster.endpoint - description = "The endpoint of the Aurora cluster" -} - -output "aurora_role_name" { - description = "The name of the aurora IAM role" - value = var.iam_create_aurora_role ? aws_iam_role.aurora_role[0].name : "" - sensitive = false -} - -output "aurora_role_arn" { - description = "The ARN of the aurora IAM role" - value = var.iam_create_aurora_role ? aws_iam_role.aurora_role[0].arn : "" - sensitive = false -} - -output "aurora_policy_arn" { - description = "The ARN of the aurora access policy" - value = var.iam_create_aurora_role ? aws_iam_policy.aurora_access_policy[0].arn : "" - sensitive = false -} diff --git a/modules/aurora/outputs.tf b/modules/aurora/outputs.tf new file mode 100644 index 00000000..c969887f --- /dev/null +++ b/modules/aurora/outputs.tf @@ -0,0 +1,36 @@ +output "aurora_endpoint" { + value = aws_rds_cluster.aurora_cluster.endpoint + description = "The endpoint of the Aurora cluster" +} + +output "aurora_id" { + value = aws_rds_cluster.aurora_cluster.id + description = "RDS Cluster Identifier" +} + +output "aurora_cluster_identifier" { + value = aws_rds_cluster.aurora_cluster.cluster_identifier + description = "RDS Cluster Identifier" +} + +output "aurora_cluster_resource_id" { + value = aws_rds_cluster.aurora_cluster.cluster_resource_id + description = "RDS Cluster Resource ID" +} + +// Output for Role ARNs +output "aurora_iam_role_arns" { + description = "Map of IAM role names to their ARNs" + + value = { for role_name, role in aws_iam_role.roles : role_name => role.arn } + sensitive = false +} + +// Output for Policy ARNs +output "aurora_iam_role_access_policy_arns" { + description = "Map of IAM role names to their access policy ARNs" + + value = { for role_name, policy in aws_iam_policy.access_policies : role_name => policy.arn } + + sensitive = false +} diff --git a/modules/aurora/role.tf b/modules/aurora/role.tf index 1df6461a..14ebf931 100644 --- a/modules/aurora/role.tf +++ b/modules/aurora/role.tf @@ -1,25 +1,25 @@ -// IAM Role for Aurora -resource "aws_iam_role" "aurora_role" { - count = var.iam_create_aurora_role ? 1 : 0 +// IAM Role +resource "aws_iam_role" "roles" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - name = var.iam_aurora_role_name - assume_role_policy = var.iam_role_trust_policy + name = each.key + assume_role_policy = each.value.trust_policy } -// IAM Policy for Aurora Access -resource "aws_iam_policy" "aurora_access_policy" { - count = var.iam_create_aurora_role ? 1 : 0 +// IAM Policy for Access +resource "aws_iam_policy" "access_policies" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - name = "${var.iam_aurora_role_name}-access-policy" - description = "Access policy for Aurora" + name = "${each.key}-access-policy" + description = "Access policy for ${each.key}" - policy = var.iam_aurora_access_policy + policy = each.value.access_policy } // Attach the policy to the role -resource "aws_iam_role_policy_attachment" "attach_aurora_policy" { - count = var.iam_create_aurora_role ? 1 : 0 +resource "aws_iam_role_policy_attachment" "attach_policies" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - role = aws_iam_role.aurora_role[0].name - policy_arn = aws_iam_policy.aurora_access_policy[0].arn + role = aws_iam_role.roles[each.key].name + policy_arn = aws_iam_policy.access_policies[each.key].arn } diff --git a/modules/aurora/variables.tf b/modules/aurora/variables.tf index aaf5bc58..f637525c 100644 --- a/modules/aurora/variables.tf +++ b/modules/aurora/variables.tf @@ -94,60 +94,61 @@ variable "default_database_name" { description = "The name for the automatically created database on cluster creation." } -variable "iam_create_aurora_role" { - description = "Flag to determine if the Aurora IAM role should be created, if true, this module will create a role. Please ensure that iam_auth_enabled is set to `true`" - type = bool - default = false -} - -variable "iam_aurora_role_name" { - description = "Name of the AuroraRole IAM role" - type = string - default = "AuroraRole" -} - -variable "iam_role_trust_policy" { - description = "Assume role trust policy for Aurora role" - type = string - default = <:oidc-provider/oidc.eks..amazonaws.com/id/" - }, - "Action": "sts:AssumeRoleWithWebIdentity", - "Condition": { - "StringEquals": { - "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" - } - } - } - ] - } - -EOF -} - -variable "iam_aurora_access_policy" { - # see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html - description = "Access policy for Aurora allowing access" - type = string - default = <::dbuser:/" - } - ] - } - -EOF +variable "iam_roles_with_policies" { + description = "List of roles with their trust and access policies" + type = list(object({ + # Name of the Role to create + role_name = string + + # Assume role trust policy for this Aurora role as a json string + trust_policy = string + + # Access policy for Aurora allowing access as a json string + # see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html + # Since the DbiResourceId may be unknown during the apply process, and because each instance of the RDS cluster contains its own DbiResourceId, + # we use the wildcard `dbuser:*` to apply to all database instances. + # Example: + # [ + # { + # role_name = "AuroraRole" + # trust_policy = + # { + # "Version": "2012-10-17", + # "Statement": [ + # { + # "Effect": "Allow", + # "Principal": { + # "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + # }, + # "Action": "sts:AssumeRoleWithWebIdentity", + # "Condition": { + # "StringEquals": { + # "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + # } + # } + # } + # ] + # } + # + # access_policy = + # { + # "Version": "2012-10-17", + # "Statement": [ + # { + # "Effect": "Allow", + # "Action": [ + # "rds-db:connect" + # ], + # "Resource": "arn:aws:rds-db:::dbuser:*/" + # } + # ] + # } + # + # } + # ] + access_policy = string + })) + + # By default, don't create any role and associated policies. + default = [] } diff --git a/modules/eks-cluster/README.md b/modules/eks-cluster/README.md index e3a29f0a..a9c034f9 100644 --- a/modules/eks-cluster/README.md +++ b/modules/eks-cluster/README.md @@ -54,6 +54,7 @@ module "eks_cluster" { | [cluster\_node\_ipv4\_cidr](#input\_cluster\_node\_ipv4\_cidr) | The CIDR block for public and private subnets of loadbalancers and nodes. Between /28 and /16. | `string` | `"10.192.0.0/16"` | no | | [cluster\_service\_ipv4\_cidr](#input\_cluster\_service\_ipv4\_cidr) | The CIDR block to assign Kubernetes service IP addresses from. Between /24 and /12. | `string` | `"10.190.0.0/16"` | no | | [cluster\_tags](#input\_cluster\_tags) | A map of additional tags to add to the cluster | `map(string)` | `{}` | no | +| [create\_ebs\_gp3\_default\_storage\_class](#input\_create\_ebs\_gp3\_default\_storage\_class) | Flag to determine if the kubernetes\_storage\_class should be created using EBS-CSI and set on GP3 by default. Set to 'false' to skip creating the storage class, useful for avoiding dependency issues during EKS cluster deletion. | `bool` | `true` | no | | [enable\_cluster\_creator\_admin\_permissions](#input\_enable\_cluster\_creator\_admin\_permissions) | Indicates whether or not to add the cluster creator (the identity used by Terraform) as an administrator via access entry. | `bool` | `true` | no | | [kubernetes\_version](#input\_kubernetes\_version) | Kubernetes version to be used by EKS | `string` | `"1.30"` | no | | [name](#input\_name) | Name being used for relevant resources - including EKS cluster name | `string` | n/a | yes | @@ -73,6 +74,7 @@ module "eks_cluster" { | [access\_entries](#output\_access\_entries) | Map of access entries created and their attributes | | [aws\_caller\_identity\_account\_id](#output\_aws\_caller\_identity\_account\_id) | Account ID of the current AWS account | | [cert\_manager\_arn](#output\_cert\_manager\_arn) | Amazon Resource Name of the cert-manager IAM role used for IAM Roles to Service Accounts mappings | +| [cluster\_arn](#output\_cluster\_arn) | ARN of the cluster | | [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server | | [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster | | [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster | diff --git a/modules/eks-cluster/cluster.tf b/modules/eks-cluster/cluster.tf index 4be9e593..8b13c1d0 100644 --- a/modules/eks-cluster/cluster.tf +++ b/modules/eks-cluster/cluster.tf @@ -154,6 +154,8 @@ provider "kubernetes" { # gp3 storage class resource "kubernetes_storage_class_v1" "ebs_sc" { + count = var.create_ebs_gp3_default_storage_class ? 1 : 0 + metadata { name = "ebs-sc" annotations = { diff --git a/modules/eks-cluster/outputs.tf b/modules/eks-cluster/outputs.tf index 164473ab..8a7c2174 100644 --- a/modules/eks-cluster/outputs.tf +++ b/modules/eks-cluster/outputs.tf @@ -36,11 +36,17 @@ output "cluster_iam_role_arn" { description = "IAM role ARN of the EKS cluster" value = module.eks.cluster_iam_role_arn } + output "access_entries" { description = "Map of access entries created and their attributes" value = module.eks.access_entries } +output "cluster_arn" { + description = "ARN of the cluster" + value = module.eks.cluster_arn +} + ################################################################################ # IRSA ################################################################################ diff --git a/modules/eks-cluster/variables.tf b/modules/eks-cluster/variables.tf index 7609e0ff..d279f311 100644 --- a/modules/eks-cluster/variables.tf +++ b/modules/eks-cluster/variables.tf @@ -13,7 +13,7 @@ variable "name" { variable "kubernetes_version" { type = string description = "Kubernetes version to be used by EKS" - # renovate: datasource=endoflife-date depName=amazon-eks versioning=semver + # renovate: datasource=endoflife-date depName=amazon-eks versioning=loose default = "1.30" } @@ -99,3 +99,9 @@ variable "enable_cluster_creator_admin_permissions" { type = bool default = true } + +variable "create_ebs_gp3_default_storage_class" { + type = bool + default = true + description = "Flag to determine if the kubernetes_storage_class should be created using EBS-CSI and set on GP3 by default. Set to 'false' to skip creating the storage class, useful for avoiding dependency issues during EKS cluster deletion." +} diff --git a/modules/fixtures/postgres-client.yml b/modules/fixtures/postgres-client.yml index 751c188d..3722f704 100644 --- a/modules/fixtures/postgres-client.yml +++ b/modules/fixtures/postgres-client.yml @@ -23,13 +23,12 @@ spec: set -o pipefail echo "Installing dependencies..." - yum install -y postgresql15 unzip awscli-2 + yum install -y postgresql15 awscli-2 echo "Creating IRSA db user using admin user" psql -h $AURORA_ENDPOINT -p $AURORA_PORT "sslmode=require dbname=$AURORA_DB_NAME user=$AURORA_USERNAME password=$AURORA_PASSWORD" \ -c "CREATE USER \"${AURORA_USERNAME_IRSA}\" WITH LOGIN;" \ -c "GRANT rds_iam TO \"${AURORA_USERNAME_IRSA}\";" \ - -c "GRANT rds_superuser TO \"${AURORA_USERNAME_IRSA}\";" \ -c "GRANT ALL PRIVILEGES ON DATABASE \"${AURORA_DB_NAME}\" TO \"${AURORA_USERNAME_IRSA}\";" \ -c "SELECT aurora_version();" \ -c "SELECT version();" -c "\du" diff --git a/modules/opensearch/README.md b/modules/opensearch/README.md index f3086546..e3666761 100644 --- a/modules/opensearch/README.md +++ b/modules/opensearch/README.md @@ -13,7 +13,6 @@ module "opensearch_domain" { domain_name = "my-opensearch-domain" engine_version = "2.15" subnet_ids = module.eks_cluster.private_subnet_ids - security_group_ids = module.eks_cluster.security_group_ids vpc_id = module.eks_cluster.vpc_id cidr_blocks = concat(module.eks_cluster.private_vpc_cidr_blocks, module.eks_cluster.public_vpc_cidr_blocks) @@ -68,9 +67,9 @@ No modules. | Name | Type | |------|------| -| [aws_iam_policy.opensearch_access_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | -| [aws_iam_role.opensearch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.attach_opensearch_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_policy.access_policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.attach_policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_kms_key.kms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | | [aws_opensearch_domain.opensearch_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/opensearch_domain) | resource | | [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | @@ -85,6 +84,7 @@ No modules. | [advanced\_security\_anonymous\_auth\_enabled](#input\_advanced\_security\_anonymous\_auth\_enabled) | Whether the anonymous auth is enabled. | `bool` | `false` | no | | [advanced\_security\_enabled](#input\_advanced\_security\_enabled) | Whether advanced security is enabled. | `bool` | `false` | no | | [advanced\_security\_internal\_user\_database\_enabled](#input\_advanced\_security\_internal\_user\_database\_enabled) | Whether the internal user database is enabled. | `bool` | `false` | no | +| [advanced\_security\_master\_user\_arn](#input\_advanced\_security\_master\_user\_arn) | ARN for the main user. Only specify if `advanced_security_internal_user_database_enabled` is set to false. | `string` | `""` | no | | [advanced\_security\_master\_user\_name](#input\_advanced\_security\_master\_user\_name) | Main user's username, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `advanced_security_internal_user_database_enabled` is set to true. | `string` | `"opensearch-admin"` | no | | [advanced\_security\_master\_user\_password](#input\_advanced\_security\_master\_user\_password) | Main user's password, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `advanced_security_internal_user_database_enabled` is set to true. | `string` | `""` | no | | [auto\_software\_update\_enabled](#input\_auto\_software\_update\_enabled) | Software update auto for the domain. | `bool` | `false` | no | @@ -105,10 +105,7 @@ No modules. | [ebs\_volume\_type](#input\_ebs\_volume\_type) | Type of EBS volumes attached to data nodes. | `string` | `"gp3"` | no | | [enable\_access\_policy](#input\_enable\_access\_policy) | Determines whether an access policy will be applied to the domain | `bool` | `true` | no | | [engine\_version](#input\_engine\_version) | OpenSearch version for the domain. | `string` | `"2.15"` | no | -| [iam\_create\_opensearch\_role](#input\_iam\_create\_opensearch\_role) | Flag to determine if the OpenSearch role should be created | `bool` | `false` | no | -| [iam\_opensearch\_access\_policy](#input\_iam\_opensearch\_access\_policy) | Access policy for OpenSearch allowing access | `string` | `" {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"es:ESHttpGet\",\n \"es:ESHttpPut\",\n \"es:ESHttpPost\"\n ],\n \"Resource\": \"arn:aws:es:::domain//*\"\n }\n ]\n }\n\n"` | no | -| [iam\_opensearch\_role\_name](#input\_iam\_opensearch\_role\_name) | Name of the OpenSearch IAM role | `string` | `"OpenSearchRole"` | no | -| [iam\_role\_trust\_policy](#input\_iam\_role\_trust\_policy) | Assume role trust policy for OpenSearch role | `string` | `" {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"Federated\": \"arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Condition\": {\n \"StringEquals\": {\n \"oidc.eks..amazonaws.com/id/:sub\": \"system:serviceaccount::\"\n }\n }\n }\n ]\n }\n\n"` | no | +| [iam\_roles\_with\_policies](#input\_iam\_roles\_with\_policies) | List of roles with their trust and access policies |
list(object({
# Name of the Role to create
role_name = string

# Assume role trust policy for this Aurora role as a json string
trust_policy = string

# Access policy for Aurora allowing access as a json string
# see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html
# Example:
# [
# {
# role_name = "OpenSearchRole"
# trust_policy =
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "Principal": {
# "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/"
# },
# "Action": "sts:AssumeRoleWithWebIdentity",
# "Condition": {
# "StringEquals": {
# "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::"
# }
# }
# }
# ]
# }
#
# access_policy =
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "Action": [
# "es:DescribeElasticsearchDomains",
# "es:DescribeElasticsearchInstanceTypeLimits",
# "es:DescribeReservedElasticsearchInstanceOfferings",
# "es:DescribeReservedElasticsearchInstances",
# "es:GetCompatibleElasticsearchVersions",
# "es:ListDomainNames",
# "es:ListElasticsearchInstanceTypes",
# "es:ListElasticsearchVersions",
# "es:DescribeElasticsearchDomain",
# "es:DescribeElasticsearchDomainConfig",
# "es:ESHttpGet",
# "es:ESHttpHead",
# "es:GetUpgradeHistory",
# "es:GetUpgradeStatus",
# "es:ListTags",
# "es:AddTags",
# "es:RemoveTags",
# "es:ESHttpDelete",
# "es:ESHttpPost",
# "es:ESHttpPut"
# ],
# "Resource": "arn:aws:es:::domain//*"
# }
# ]
# }
#
# }
# ]
access_policy = string
}))
| `[]` | no | | [instance\_count](#input\_instance\_count) | Number of instances in the cluster. | `number` | `3` | no | | [instance\_type](#input\_instance\_type) | Instance type of data nodes in the cluster. | `string` | `"t3.small.search"` | no | | [ip\_address\_type](#input\_ip\_address\_type) | The IP address type for the endpoint. Valid values are ipv4 and dualstack | `string` | `"ipv4"` | no | @@ -137,9 +134,8 @@ No modules. | [opensearch\_domain\_arn](#output\_opensearch\_domain\_arn) | The ARN of the OpenSearch domain | | [opensearch\_domain\_endpoint](#output\_opensearch\_domain\_endpoint) | The endpoint of the OpenSearch domain | | [opensearch\_domain\_id](#output\_opensearch\_domain\_id) | The ID of the OpenSearch domain | -| [opensearch\_policy\_arn](#output\_opensearch\_policy\_arn) | The ARN of the OpenSearch access policy | -| [opensearch\_role\_arn](#output\_opensearch\_role\_arn) | The ARN of the OpenSearch IAM role | -| [opensearch\_role\_name](#output\_opensearch\_role\_name) | The name of the OpenSearch IAM role | +| [opensearch\_iam\_role\_access\_policy\_arns](#output\_opensearch\_iam\_role\_access\_policy\_arns) | Map of IAM role names to their access policy ARNs | +| [opensearch\_iam\_role\_arns](#output\_opensearch\_iam\_role\_arns) | Map of IAM role names to their ARNs | | [security\_group\_id](#output\_security\_group\_id) | The ID of the security group used by OpenSearch | | [security\_group\_rule\_egress](#output\_security\_group\_rule\_egress) | Egress rule information for OpenSearch security group | | [security\_group\_rule\_ingress](#output\_security\_group\_rule\_ingress) | Ingress rule information for OpenSearch security group | diff --git a/modules/opensearch/main.tf b/modules/opensearch/main.tf index c1de0203..803401cc 100644 --- a/modules/opensearch/main.tf +++ b/modules/opensearch/main.tf @@ -51,6 +51,9 @@ resource "aws_opensearch_domain" "opensearch_cluster" { master_user_options { master_user_name = var.advanced_security_master_user_name master_user_password = var.advanced_security_master_user_password + + # Only use master_user_arn if internal_user_database_enabled is false + master_user_arn = var.advanced_security_internal_user_database_enabled ? null : var.advanced_security_master_user_arn } anonymous_auth_enabled = var.advanced_security_anonymous_auth_enabled diff --git a/modules/opensearch/outputs.tf b/modules/opensearch/outputs.tf index a7a295d7..d9a18c4e 100644 --- a/modules/opensearch/outputs.tf +++ b/modules/opensearch/outputs.tf @@ -53,20 +53,19 @@ output "security_group_rule_egress" { sensitive = false } -output "opensearch_role_name" { - description = "The name of the OpenSearch IAM role" - value = var.iam_create_opensearch_role ? aws_iam_role.opensearch[0].name : "" - sensitive = false -} +// Output for Role ARNs +output "opensearch_iam_role_arns" { + description = "Map of IAM role names to their ARNs" -output "opensearch_role_arn" { - description = "The ARN of the OpenSearch IAM role" - value = var.iam_create_opensearch_role ? aws_iam_role.opensearch[0].arn : "" - sensitive = false + value = { for role_name, role in aws_iam_role.roles : role_name => role.arn } + sensitive = false } -output "opensearch_policy_arn" { - description = "The ARN of the OpenSearch access policy" - value = var.iam_create_opensearch_role ? aws_iam_role.opensearch[0].arn : "" - sensitive = false +// Output for Policy ARNs +output "opensearch_iam_role_access_policy_arns" { + description = "Map of IAM role names to their access policy ARNs" + + value = { for role_name, policy in aws_iam_policy.access_policies : role_name => policy.arn } + + sensitive = false } diff --git a/modules/opensearch/role.tf b/modules/opensearch/role.tf index be12de8c..14ebf931 100644 --- a/modules/opensearch/role.tf +++ b/modules/opensearch/role.tf @@ -1,25 +1,25 @@ -// IAM Role for OpenSearch -resource "aws_iam_role" "opensearch" { - count = var.iam_create_opensearch_role ? 1 : 0 +// IAM Role +resource "aws_iam_role" "roles" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - name = var.iam_opensearch_role_name - assume_role_policy = var.iam_role_trust_policy + name = each.key + assume_role_policy = each.value.trust_policy } -// IAM Policy for OpenSearch Access -resource "aws_iam_policy" "opensearch_access_policy" { - count = var.iam_create_opensearch_role ? 1 : 0 +// IAM Policy for Access +resource "aws_iam_policy" "access_policies" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - name = "${var.iam_opensearch_role_name}-access-policy" - description = "Access policy for OpenSearch" + name = "${each.key}-access-policy" + description = "Access policy for ${each.key}" - policy = var.iam_opensearch_access_policy + policy = each.value.access_policy } // Attach the policy to the role -resource "aws_iam_role_policy_attachment" "attach_opensearch_policy" { - count = var.iam_create_opensearch_role ? 1 : 0 +resource "aws_iam_role_policy_attachment" "attach_policies" { + for_each = { for idx, role in var.iam_roles_with_policies : role.role_name => role } - role = aws_iam_role.opensearch[0].name - policy_arn = aws_iam_policy.opensearch_access_policy[0].arn + role = aws_iam_role.roles[each.key].name + policy_arn = aws_iam_policy.access_policies[each.key].arn } diff --git a/modules/opensearch/variables.tf b/modules/opensearch/variables.tf index 66ac4999..cb6827e4 100644 --- a/modules/opensearch/variables.tf +++ b/modules/opensearch/variables.tf @@ -149,6 +149,12 @@ variable "advanced_security_internal_user_database_enabled" { description = "Whether the internal user database is enabled." } +variable "advanced_security_master_user_arn" { + type = string + default = "" + description = "ARN for the main user. Only specify if `advanced_security_internal_user_database_enabled` is set to false." +} + variable "advanced_security_master_user_name" { type = string default = "opensearch-admin" @@ -257,61 +263,79 @@ variable "kms_key_tags" { default = {} } -variable "iam_create_opensearch_role" { - description = "Flag to determine if the OpenSearch role should be created" - type = bool - default = false -} - -variable "iam_opensearch_role_name" { - description = "Name of the OpenSearch IAM role" - type = string - default = "OpenSearchRole" -} - -variable "iam_role_trust_policy" { - description = "Assume role trust policy for OpenSearch role" - type = string - default = <:oidc-provider/oidc.eks..amazonaws.com/id/" - }, - "Action": "sts:AssumeRoleWithWebIdentity", - "Condition": { - "StringEquals": { - "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" - } - } - } - ] - } - -EOF -} - -variable "iam_opensearch_access_policy" { - description = "Access policy for OpenSearch allowing access" - type = string - default = <::domain//*" - } - ] - } - -EOF +variable "iam_roles_with_policies" { + description = "List of roles with their trust and access policies" + + type = list(object({ + # Name of the Role to create + role_name = string + + # Assume role trust policy for this Aurora role as a json string + trust_policy = string + + # Access policy for Aurora allowing access as a json string + # see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html + # Example: + # [ + # { + # role_name = "OpenSearchRole" + # trust_policy = + # { + # "Version": "2012-10-17", + # "Statement": [ + # { + # "Effect": "Allow", + # "Principal": { + # "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + # }, + # "Action": "sts:AssumeRoleWithWebIdentity", + # "Condition": { + # "StringEquals": { + # "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + # } + # } + # } + # ] + # } + # + # access_policy = + # { + # "Version": "2012-10-17", + # "Statement": [ + # { + # "Effect": "Allow", + # "Action": [ + # "es:DescribeElasticsearchDomains", + # "es:DescribeElasticsearchInstanceTypeLimits", + # "es:DescribeReservedElasticsearchInstanceOfferings", + # "es:DescribeReservedElasticsearchInstances", + # "es:GetCompatibleElasticsearchVersions", + # "es:ListDomainNames", + # "es:ListElasticsearchInstanceTypes", + # "es:ListElasticsearchVersions", + # "es:DescribeElasticsearchDomain", + # "es:DescribeElasticsearchDomainConfig", + # "es:ESHttpGet", + # "es:ESHttpHead", + # "es:GetUpgradeHistory", + # "es:GetUpgradeStatus", + # "es:ListTags", + # "es:AddTags", + # "es:RemoveTags", + # "es:ESHttpDelete", + # "es:ESHttpPost", + # "es:ESHttpPut" + # ], + # "Resource": "arn:aws:es:::domain//*" + # } + # ] + # } + # + # } + # ] + access_policy = string + })) + + # By default, don't create any role and associated policies. + default = [] } diff --git a/test/src/custom_eks_opensearch_test.go b/test/src/custom_eks_opensearch_test.go index 77fb0eb5..f27b6371 100644 --- a/test/src/custom_eks_opensearch_test.go +++ b/test/src/custom_eks_opensearch_test.go @@ -208,15 +208,21 @@ func (suite *CustomEKSOpenSearchTestSuite) TestCustomEKSAndOpenSearch() { ] }`, accountId, oidcProviderID, oidcProviderID, openSearchNamespace, openSearchServiceAccount) + iamRolesWithPolicies := []interface{}{ + map[string]interface{}{ + "role_name": openSearchRole, + // escape and put everything on a single line + "trust_policy": strings.ReplaceAll(strings.ReplaceAll(iamRoleTrustPolicy, "\n", " "), `"`, `\"`), + "access_policy": strings.ReplaceAll(strings.ReplaceAll(openSearchAccessPolicy, "\n", " "), `"`, `\"`), + }, + } + varsConfigOpenSearch := map[string]interface{}{ - "domain_name": opensearchDomainName, - "subnet_ids": result.Cluster.ResourcesVpcConfig.SubnetIds, - "cidr_blocks": append(publicBlocks, privateBlocks...), - "vpc_id": *result.Cluster.ResourcesVpcConfig.VpcId, - "iam_create_opensearch_role": true, - "iam_opensearch_role_name": openSearchRole, - "iam_role_trust_policy": iamRoleTrustPolicy, - "iam_opensearch_access_policy": openSearchAccessPolicy, + "domain_name": opensearchDomainName, + "subnet_ids": result.Cluster.ResourcesVpcConfig.SubnetIds, + "cidr_blocks": append(publicBlocks, privateBlocks...), + "vpc_id": *result.Cluster.ResourcesVpcConfig.VpcId, + "iam_roles_with_policies": iamRolesWithPolicies, } tfModuleOpenSearch := "opensearch/" @@ -273,14 +279,14 @@ func (suite *CustomEKSOpenSearchTestSuite) TestCustomEKSAndOpenSearch() { // Retrieve the IAM Role associated with OpenSearch describeOpenSearchRoleInput := &iam.GetRoleInput{ - RoleName: aws.String(varsConfigOpenSearch["iam_opensearch_role_name"].(string)), + RoleName: aws.String(openSearchRole), } _, err = iamSvc.GetRole(context.Background(), describeOpenSearchRoleInput) suite.Require().NoError(err) // Verify IAM Policy Attachment listAttachedPoliciesInput := &iam.ListAttachedRolePoliciesInput{ - RoleName: aws.String(varsConfigOpenSearch["iam_opensearch_role_name"].(string)), + RoleName: aws.String(openSearchRole), } _, err = iamSvc.ListAttachedRolePolicies(context.Background(), listAttachedPoliciesInput) suite.Require().NoError(err) diff --git a/test/src/custom_eks_rds_test.go b/test/src/custom_eks_rds_test.go index 28dd8dff..f23e1e71 100644 --- a/test/src/custom_eks_rds_test.go +++ b/test/src/custom_eks_rds_test.go @@ -164,8 +164,7 @@ func (suite *CustomEKSRDSTestSuite) TestCustomEKSAndRDS() { // Define the ARN for RDS IAM DB Auth auroraIRSAUsername := "myirsauser" - auroraArn := fmt.Sprintf("arn:aws:rds-db:%s:%s:dbuser:%s/%s", suite.region, accountId, auroraClusterName, auroraIRSAUsername) - suite.sugaredLogger.Infow("Aurora RDS IAM infos", "accountId", accountId, "auroraArn", auroraArn) + suite.sugaredLogger.Infow("Aurora RDS IAM infos", "accountId", accountId) utils.GenerateKubeConfigFromAWS(suite.T(), suite.region, suite.clusterName, utils.GetAwsProfile(), suite.kubeConfigPath) @@ -188,10 +187,10 @@ func (suite *CustomEKSRDSTestSuite) TestCustomEKSAndRDS() { "Action": [ "rds-db:connect" ], - "Resource": "arn:aws:rds-db:%s:%s:dbuser:%s/%s" + "Resource": "arn:aws:rds-db:%s:%s:dbuser:*/%s" } ] -}`, suite.region, accountId, auroraClusterName, auroraIRSAUsername) +}`, suite.region, accountId, auroraIRSAUsername) // Define the trust policy for Aurora IAM role iamRoleTrustPolicy := fmt.Sprintf(`{ @@ -212,20 +211,26 @@ func (suite *CustomEKSRDSTestSuite) TestCustomEKSAndRDS() { ] }`, accountId, oidcProviderID, oidcProviderID, auroraNamespace, auroraServiceAccount) + iamRolesWithPolicies := []interface{}{ + map[string]interface{}{ + "role_name": auroraRole, + // escape and put everything on a single line + "trust_policy": strings.ReplaceAll(strings.ReplaceAll(iamRoleTrustPolicy, "\n", " "), `"`, `\"`), + "access_policy": strings.ReplaceAll(strings.ReplaceAll(auroraAccessPolicy, "\n", " "), `"`, `\"`), + }, + } + varsConfigAurora := map[string]interface{}{ - "username": auroraUsername, - "password": auroraPassword, - "default_database_name": auroraDatabase, - "cluster_name": auroraClusterName, - "subnet_ids": result.Cluster.ResourcesVpcConfig.SubnetIds, - "vpc_id": *result.Cluster.ResourcesVpcConfig.VpcId, - "availability_zones": []string{fmt.Sprintf("%sa", suite.region), fmt.Sprintf("%sb", suite.region), fmt.Sprintf("%sc", suite.region)}, - "cidr_blocks": append(publicBlocks, privateBlocks...), - "iam_auth_enabled": true, - "iam_create_aurora_role": true, - "iam_aurora_role_name": auroraRole, - "iam_role_trust_policy": iamRoleTrustPolicy, - "iam_aurora_access_policy": auroraAccessPolicy, + "username": auroraUsername, + "password": auroraPassword, + "default_database_name": auroraDatabase, + "cluster_name": auroraClusterName, + "subnet_ids": result.Cluster.ResourcesVpcConfig.SubnetIds, + "vpc_id": *result.Cluster.ResourcesVpcConfig.VpcId, + "availability_zones": []string{fmt.Sprintf("%sa", suite.region), fmt.Sprintf("%sb", suite.region), fmt.Sprintf("%sc", suite.region)}, + "cidr_blocks": append(publicBlocks, privateBlocks...), + "iam_auth_enabled": true, + "iam_roles_with_policies": iamRolesWithPolicies, } tfModuleAurora := "aurora/" @@ -329,7 +334,7 @@ func (suite *CustomEKSRDSTestSuite) TestCustomEKSAndRDS() { suite.Require().NoError(err) expectedRDSAZ := []string{fmt.Sprintf("%sa", suite.region), fmt.Sprintf("%sb", suite.region), fmt.Sprintf("%sc", suite.region)} - suite.Assert().Equal(varsConfigAurora["iam_auth_enabled"].(bool), *describeDBClusterOutput.DBClusters[0].IAMDatabaseAuthenticationEnabled) + suite.Assert().Equal(true, *describeDBClusterOutput.DBClusters[0].IAMDatabaseAuthenticationEnabled) suite.Assert().Equal(varsConfigAurora["username"].(string), *describeDBClusterOutput.DBClusters[0].MasterUsername) suite.Assert().Equal(auroraDatabase, *describeDBClusterOutput.DBClusters[0].DatabaseName) suite.Assert().Equal(int32(5432), *describeDBClusterOutput.DBClusters[0].Port)