diff --git a/infrastructure/aws/iam/cert_manager/.terraform.lock.hcl b/infrastructure/aws/iam/cert_manager/.terraform.lock.hcl
new file mode 100644
index 00000000..821b0484
--- /dev/null
+++ b/infrastructure/aws/iam/cert_manager/.terraform.lock.hcl
@@ -0,0 +1,25 @@
+# This file is maintained automatically by "tofu init".
+# Manual edits may be lost in future updates.
+
+provider "registry.opentofu.org/hashicorp/aws" {
+ version = "6.52.0"
+ constraints = ">= 6.28.0"
+ hashes = [
+ "h1:8H3TGxUyZ83L8spIqyrPez0BqCUAlZEd+7Y7O60/xOk=",
+ "zh:0ad03e39cef9ca83c7663efcf618eb49dd72e5930406311ec063595551e1afab",
+ "zh:24f831fa500a7778ffcb7d770250bb20caa0c86506651ed7b4ce82bf4743edfc",
+ "zh:270188d0e43e14ed74cce315e73ade0afd1bda36a5d3626270109529614f4d9e",
+ "zh:387154e5bdb49a825739414a7b859865d10411677ef9eb3f8c082709a91ac2e8",
+ "zh:3d458b379c48d67dfd50188df05f9477c752ed0913c52d342f3d311e51980d05",
+ "zh:40f5d2056829d48080abc1081cf1747724bacdc86764a5ee02422734adb15e08",
+ "zh:57837cc69ad9c1959186150b3705ca1f34e6542e8f05ae106eb747577617d8b3",
+ "zh:81d3e77d89c8819a4ceaa94b6200679a4e4d2d682c6204003a2a18d0fd587761",
+ "zh:8823b3663c5b4ec5c3bb18ccacd6aa919c52dfa876cc850afc25c4f1fdf453bc",
+ "zh:8999caef5b21d7794a216dd43265a851b098dd73e11a62022ceb2ecb8b89f172",
+ "zh:915621a7335e9d351a62a6ffabf396df98b4f116fb12a31bf4c6747e1ecc7e55",
+ "zh:9f7264c34db8d6a00bacb0119bd284f18c43a4617427703650719be25fae4b2d",
+ "zh:ba466658cf7e5549582b0eb8ed8ddce52b2ecdd5b31da94849f66cc8fa1f18e1",
+ "zh:befccb34cb734687e95211606931c09a24f403bb634087743cf75f058c944200",
+ "zh:fa749a6535df4020d90a4767fee943fdd9c606938ce4f4e1136e8ae6ba437a85",
+ ]
+}
diff --git a/infrastructure/aws/iam/cert_manager/README.md b/infrastructure/aws/iam/cert_manager/README.md
index d9b2f9aa..cb5b2dc6 100644
--- a/infrastructure/aws/iam/cert_manager/README.md
+++ b/infrastructure/aws/iam/cert_manager/README.md
@@ -2,23 +2,25 @@
## Description
-Creates an IAM role and policy for cert-manager on EKS, enabling DNS01 ACME challenge validation via Route53 hosted zones using IRSA
+Creates an IAM role and policy for cert-manager on EKS, enabling DNS01 ACME challenge validation via Route53. Supports both IRSA (OIDC federation) and EKS Pod Identity as the identity mechanism.
## Architecture
-An aws_iam_policy is created granting Route53 permissions (GetChange, ChangeResourceRecordSets, ListResourceRecordSets, ListHostedZonesByName) scoped to the provided public and/or private hosted zone ARNs. The terraform-aws-modules/iam iam-role-for-service-accounts module creates an aws_iam_role with an OIDC trust policy bound to the cert-manager Kubernetes service account in the cert-manager namespace. The OIDC provider ARN and cluster name flow into the role naming and trust relationship, while the hosted zone IDs are dynamically filtered and converted to ARNs via a local for expression. The role ARN is exposed as an output for use by the cert-manager Helm release or Kubernetes service account annotation.
+An aws_iam_policy is created granting Route53 permissions (GetChange, ChangeResourceRecordSets, ListResourceRecordSets, ListHostedZonesByName) scoped to the provided public and/or private hosted zone ARNs. The `identity_mode` variable selects the authentication mechanism: in `irsa` mode the terraform-aws-modules/iam community module creates an aws_iam_role with an OIDC trust policy; in `pod_identity` mode a native aws_iam_role is created with a trust policy for `pods.eks.amazonaws.com` and an `aws_eks_pod_identity_association` binds it to the cert-manager service account. The role ARN is exposed as an output in both modes.
## Features
-- Creates an IAM role with OIDC trust scoped to the cert-manager Kubernetes service account via IRSA
+- Supports IRSA (OIDC) and EKS Pod Identity via `identity_mode` variable (default: `irsa`)
- Creates an IAM policy granting Route53 permissions required for DNS01 ACME challenge validation
- Supports both public and private Route53 hosted zones with dynamic ARN construction
- Enforces that at least one of public or private hosted zone IDs is provided via input validation
- Scopes Route53 ChangeResourceRecordSets and ListResourceRecordSets permissions to only the specified hosted zones
-- Outputs the cert-manager IAM role ARN for use in service account annotations or Helm chart values
+- Outputs the cert-manager IAM role ARN in both identity modes
## Basic Usage
+### IRSA (default)
+
```hcl
module "cert_manager" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v5.2.0"
@@ -28,6 +30,17 @@ module "cert_manager" {
}
```
+### EKS Pod Identity
+
+```hcl
+module "cert_manager" {
+ source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v5.2.0"
+
+ cluster_name = "your-cluster-name"
+ identity_mode = "pod_identity"
+}
+```
+
## Using Outputs
```hcl
@@ -43,69 +56,78 @@ resource "example_resource" "this" {
## Providers
| Name | Version |
-|------|---------|
-| [aws](#provider\_aws) | n/a |
+| ---- | ------- |
+| [aws](#provider\_aws) | 6.52.0 |
## Modules
| Name | Source | Version |
-|------|--------|---------|
+| ---- | ------ | ------- |
| [nullplatform\_cert\_manager\_role](#module\_nullplatform\_cert\_manager\_role) | terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts | n/a |
## Resources
| Name | Type |
-|------|------|
+| ---- | ---- |
+| [aws_eks_pod_identity_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_pod_identity_association) | resource |
| [aws_iam_policy.nullplatform_cert_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_iam_role.pod_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
+| [aws_iam_role_policy_attachment.pod_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
## Inputs
| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| [aws\_iam\_openid\_connect\_provider\_arn](#input\_aws\_iam\_openid\_connect\_provider\_arn) | ARN of the AWS IAM OIDC provider for EKS service account authentication | `string` | n/a | yes |
+| ---- | ----------- | ---- | ------- | :------: |
+| [aws\_iam\_openid\_connect\_provider\_arn](#input\_aws\_iam\_openid\_connect\_provider\_arn) | ARN of the AWS IAM OIDC provider. Required when identity\_mode is 'irsa'; ignored when identity\_mode is 'pod\_identity'. | `string` | `null` | no |
| [cluster\_name](#input\_cluster\_name) | Name of the cluster where the policy runs | `string` | n/a | yes |
| [hosted\_zone\_private\_id](#input\_hosted\_zone\_private\_id) | ID of the private Route53 hosted zone for DNS validation. Set to null or an empty string to omit it from the IAM policy. At least one of hosted\_zone\_public\_id or hosted\_zone\_private\_id must be provided. | `string` | `null` | no |
| [hosted\_zone\_public\_id](#input\_hosted\_zone\_public\_id) | ID of the public Route53 hosted zone for DNS validation. Set to null or an empty string to omit it from the IAM policy. At least one of hosted\_zone\_public\_id or hosted\_zone\_private\_id must be provided. | `string` | `null` | no |
+| [identity\_mode](#input\_identity\_mode) | IAM identity mode: 'irsa' uses OIDC federation via the community iam-role-for-service-accounts module; 'pod\_identity' creates a native IAM role trusted by pods.eks.amazonaws.com with an EKS Pod Identity association. Default 'irsa' is backward compatible with v4.5.x — no state changes required on upgrade. Note: switching between modes on an existing deployment replaces the IAM role; cert-manager will lose permissions during the transition until apply completes. | `string` | `"irsa"` | no |
## Outputs
| Name | Description |
-|------|-------------|
+| ---- | ----------- |
| [nullplatform\_cert\_manager\_role\_arn](#output\_nullplatform\_cert\_manager\_role\_arn) | ARN of the cert-manager role |