Skip to content

Commit eba4b66

Browse files
feat(infra): AWS IAM Terraform (#5228)
* feat(infra): AWS IAM Terraform * Fixing dependency issue * Fixing more weird logic * Final cleanup * one change * oops
1 parent 3534515 commit eba4b66

File tree

8 files changed

+155
-4
lines changed

8 files changed

+155
-4
lines changed

deployment/terraform/modules/aws/eks/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,52 @@ resource "kubernetes_service_account" "s3_access" {
147147
}
148148
}
149149
}
150+
151+
# Optionally grant the IRSA role permissions to connect to RDS using IAM auth
152+
resource "aws_iam_policy" "rds_iam_connect_policy" {
153+
count = var.enable_rds_iam_for_service_account && var.rds_db_connect_arn != null ? 1 : 0
154+
name = "${module.eks.cluster_name}-rds-iam-connect-policy"
155+
description = "Allow EKS service account to connect to RDS using IAM auth"
156+
157+
policy = jsonencode({
158+
Version = "2012-10-17",
159+
Statement = [
160+
{
161+
Effect = "Allow",
162+
Action = [
163+
"rds-db:connect"
164+
],
165+
Resource = [
166+
var.rds_db_connect_arn
167+
]
168+
}
169+
]
170+
})
171+
}
172+
173+
module "irsa-rds-connect" {
174+
count = var.enable_rds_iam_for_service_account && var.rds_db_connect_arn != null ? 1 : 0
175+
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
176+
version = "4.7.0"
177+
178+
create_role = true
179+
role_name = "AmazonEKSTFRDSConnectRole-${module.eks.cluster_name}"
180+
provider_url = module.eks.oidc_provider
181+
role_policy_arns = [aws_iam_policy.rds_iam_connect_policy[0].arn]
182+
oidc_fully_qualified_subjects = [
183+
"system:serviceaccount:${var.irsa_service_account_namespace}:${var.rds_irsa_service_account_name}"
184+
]
185+
186+
depends_on = [module.eks]
187+
}
188+
189+
resource "kubernetes_service_account" "rds_connect" {
190+
count = var.enable_rds_iam_for_service_account && var.rds_db_connect_arn != null ? 1 : 0
191+
metadata {
192+
name = var.rds_irsa_service_account_name
193+
namespace = var.irsa_service_account_namespace
194+
annotations = {
195+
"eks.amazonaws.com/role-arn" = module.irsa-rds-connect[0].iam_role_arn
196+
}
197+
}
198+
}

deployment/terraform/modules/aws/eks/variables.tf

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ variable "s3_bucket_names" {
116116

117117
variable "irsa_service_account_namespace" {
118118
type = string
119-
description = "Namespace where the IRSA-enabled Kubernetes service account for S3 access will be created"
119+
description = "Namespace for IRSA-enabled Kubernetes service accounts (used by S3 and RDS)"
120120
default = "onyx"
121121
}
122122

@@ -125,3 +125,27 @@ variable "irsa_service_account_name" {
125125
description = "Name of the IRSA-enabled Kubernetes service account for S3 access"
126126
default = "onyx-s3-access"
127127
}
128+
129+
variable "enable_rds_iam_for_service_account" {
130+
type = bool
131+
description = "Whether to create a dedicated RDS IRSA role and service account (grants rds-db:connect)"
132+
default = false
133+
}
134+
135+
variable "rds_db_username" {
136+
type = string
137+
description = "Database username to allow via rds-db:connect"
138+
default = null
139+
}
140+
141+
variable "rds_db_connect_arn" {
142+
type = string
143+
description = "Full rds-db:connect ARN to allow (required when enable_rds_iam_for_service_account is true)"
144+
default = null
145+
}
146+
147+
variable "rds_irsa_service_account_name" {
148+
type = string
149+
description = "Name of the IRSA-enabled Kubernetes service account for RDS IAM auth"
150+
default = "onyx-rds-access"
151+
}

deployment/terraform/modules/aws/onyx/main.tf

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ module "postgres" {
4949
subnet_ids = local.private_subnets
5050
ingress_cidrs = [local.vpc_cidr_block]
5151

52-
username = var.postgres_username
53-
password = var.postgres_password
54-
tags = local.merged_tags
52+
username = var.postgres_username
53+
password = var.postgres_password
54+
tags = local.merged_tags
55+
enable_rds_iam_auth = var.enable_rds_iam_auth
5556
}
5657

5758
module "s3" {
@@ -70,6 +71,11 @@ module "eks" {
7071
tags = local.merged_tags
7172
s3_bucket_names = [local.bucket_name]
7273

74+
# Wire RDS IAM connection for the same IRSA service account used by apps
75+
enable_rds_iam_for_service_account = var.enable_rds_iam_auth
76+
rds_db_username = var.postgres_username
77+
rds_db_connect_arn = var.rds_db_connect_arn
78+
7379
# These variables must be defined in variables.tf or passed in via parent module
7480
public_cluster_enabled = var.public_cluster_enabled
7581
private_cluster_enabled = var.private_cluster_enabled

deployment/terraform/modules/aws/onyx/outputs.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,29 @@ output "redis_connection_url" {
66
output "cluster_name" {
77
value = module.eks.cluster_name
88
}
9+
10+
output "postgres_endpoint" {
11+
description = "RDS endpoint hostname"
12+
value = module.postgres.endpoint
13+
}
14+
15+
output "postgres_port" {
16+
description = "RDS port"
17+
value = module.postgres.port
18+
}
19+
20+
output "postgres_db_name" {
21+
description = "RDS database name"
22+
value = module.postgres.db_name
23+
}
24+
25+
output "postgres_username" {
26+
description = "RDS master username"
27+
value = module.postgres.username
28+
sensitive = true
29+
}
30+
31+
output "postgres_dbi_resource_id" {
32+
description = "RDS DB instance resource id"
33+
value = module.postgres.dbi_resource_id
34+
}

deployment/terraform/modules/aws/onyx/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ variable "redis_auth_token" {
8787
sensitive = true
8888
}
8989

90+
variable "enable_rds_iam_auth" {
91+
type = bool
92+
description = "Enable AWS IAM authentication for the RDS Postgres instance"
93+
default = false
94+
}
95+
96+
variable "rds_db_connect_arn" {
97+
type = string
98+
description = "Full rds-db:connect ARN to pass to the EKS module. Required when enable_rds_iam_auth is true."
99+
default = null
100+
}
101+
90102
# WAF Configuration Variables
91103
variable "waf_rate_limit_requests_per_5_minutes" {
92104
type = number

deployment/terraform/modules/aws/postgres/main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ resource "aws_db_instance" "this" {
3636
username = var.username
3737
password = var.password
3838

39+
# Enable IAM authentication for the RDS instance
40+
iam_database_authentication_enabled = var.enable_rds_iam_auth
41+
3942
db_subnet_group_name = aws_db_subnet_group.this.name
4043
vpc_security_group_ids = [aws_security_group.this.id]
4144
publicly_accessible = false
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
output "endpoint" {
2+
description = "RDS endpoint hostname"
3+
value = aws_db_instance.this.endpoint
4+
}
5+
6+
output "port" {
7+
description = "RDS port"
8+
value = aws_db_instance.this.port
9+
}
10+
11+
output "db_name" {
12+
description = "Database name"
13+
value = aws_db_instance.this.db_name
14+
}
15+
16+
output "username" {
17+
description = "Master username"
18+
value = aws_db_instance.this.username
19+
sensitive = true
20+
}
21+
22+
output "dbi_resource_id" {
23+
description = "DB instance resource ID used for IAM auth resource ARNs"
24+
value = aws_db_instance.this.resource_id
25+
}

deployment/terraform/modules/aws/postgres/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,9 @@ variable "tags" {
6161
description = "Tags to apply to RDS resources"
6262
default = {}
6363
}
64+
65+
variable "enable_rds_iam_auth" {
66+
type = bool
67+
description = "Enable AWS IAM database authentication for this RDS instance"
68+
default = false
69+
}

0 commit comments

Comments
 (0)