Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [5.3.0](https://github.com/nullplatform/tofu-modules/compare/v5.2.0...v5.3.0) (2026-06-26)


### Features

* **iam:** add Pod Identity support to cert-manager and external-dns modules ([#409](https://github.com/nullplatform/tofu-modules/issues/409)) ([1f4e5ff](https://github.com/nullplatform/tofu-modules/commit/1f4e5ff1a37dea78c396dcf176a1c1db308f503b))

## [5.2.0](https://github.com/nullplatform/tofu-modules/compare/v5.1.0...v5.2.0) (2026-06-25)


Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/acm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The module creates an aws_acm_certificate resource with DNS validation, which is

```hcl
module "acm" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v5.3.0"

domain_name = "your-domain-name"
zone_id = "your-zone-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/aws_load_balancer_controller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This module creates a helm_release resource to deploy the AWS Load Balancer Cont

```hcl
module "aws_load_balancer_controller" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v5.3.0"

cluster_name = "your-cluster-name"
vpc_id = "your-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This module creates an S3 bucket with versioning and server-side encryption enab

```hcl
module "backend" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v5.3.0"
}
```

Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The module conditionally creates an aws_route53_zone resource for a public hoste

```hcl
module "dns" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v5.3.0"

domain_name = "your-domain-name"
vpc_id = "your-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module wraps terraform-aws-modules/eks to create the EKS cluster (aws_eks_cl

```hcl
module "eks" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v5.3.0"

aws_subnets_private_ids = "your-aws-subnets-private-ids"
aws_vpc_vpc_id = "your-aws-vpc-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The module uses the terraform-aws-modules/iam//modules/iam-role-for-service-acco

```hcl
module "agent" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v5.3.0"

agent_namespace = "your-agent-namespace"
aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This module creates an IAM role for the AWS Load Balancer Controller using the t

```hcl
module "aws_load_balancer_controller_iam" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v5.3.0"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
Expand Down
74 changes: 29 additions & 45 deletions infrastructure/aws/iam/cert_manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,27 @@

## Description

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.
Provisions IAM roles and policies for cert-manager on EKS, supporting both IRSA (OIDC federation) and Pod Identity authentication modes with Route53 DNS01 challenge permissions

## 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 `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.
An aws_iam_policy resource is always created granting route53:GetChange, route53:ChangeResourceRecordSets, route53:ListResourceRecordSets, and route53:ListHostedZonesByName permissions scoped to the provided hosted zone ARNs. In IRSA mode, the community terraform-aws-modules/iam module creates an aws_iam_role with an OIDC trust policy and attaches the policy via the module's internal aws_iam_role_policy_attachment. In Pod Identity mode, a standalone aws_iam_role is created with a trust policy for pods.eks.amazonaws.com, an aws_iam_role_policy_attachment links the cert-manager policy, and an aws_eks_pod_identity_association binds the role to the cert-manager Kubernetes service account in the cert-manager namespace. The resulting role ARN is surfaced via an output that conditionally selects between the IRSA module output and the Pod Identity resource.

## Features

- 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 in both identity modes
- Creates aws_iam_policy granting Route53 DNS01 challenge permissions scoped to specified public and/or private hosted zones
- Configures IRSA mode using the community iam-role-for-service-accounts module with OIDC provider trust for the cert-manager service account
- Creates native aws_iam_role trusted by pods.eks.amazonaws.com and aws_eks_pod_identity_association for EKS Pod Identity mode
- Supports both public and private Route53 hosted zones simultaneously via hosted_zone_public_id and hosted_zone_private_id inputs
- Includes a moved block for backward-compatible state migration when upgrading from pre-v4.6.0 deployments using IRSA mode

## 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"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
}
```

### 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"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v5.3.0"

cluster_name = "your-cluster-name"
identity_mode = "pod_identity"
cluster_name = "your-cluster-name"
}
```

Expand All @@ -56,19 +41,19 @@ resource "example_resource" "this" {
## Providers

| Name | Version |
| ---- | ------- |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 6.52.0 |

## Modules

| Name | Source | Version |
| ---- | ------ | ------- |
|------|--------|---------|
| <a name="module_nullplatform_cert_manager_role"></a> [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 |
Expand All @@ -77,7 +62,7 @@ resource "example_resource" "this" {
## Inputs

| Name | Description | Type | Default | Required |
| ---- | ----------- | ---- | ------- | :------: |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_iam_openid_connect_provider_arn"></a> [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 |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the cluster where the policy runs | `string` | n/a | yes |
| <a name="input_hosted_zone_private_id"></a> [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 |
Expand All @@ -87,22 +72,21 @@ resource "example_resource" "this" {
## Outputs

| Name | Description |
| ---- | ----------- |
|------|-------------|
| <a name="output_nullplatform_cert_manager_role_arn"></a> [nullplatform\_cert\_manager\_role\_arn](#output\_nullplatform\_cert\_manager\_role\_arn) | ARN of the cert-manager role |
<!-- END_TF_DOCS -->

<!-- BEGIN_AI_METADATA
{
"name": "cert_manager",
"description": "Creates an IAM role and policy for cert-manager on EKS, enabling DNS01 ACME challenge validation via Route53. Supports IRSA and EKS Pod Identity via identity_mode variable.",
"architecture": "An aws_iam_policy is created granting Route53 permissions scoped to the provided hosted zone ARNs. The identity_mode variable selects the authentication mechanism: 'irsa' uses the terraform-aws-modules/iam community module to create a role with OIDC trust; 'pod_identity' creates a native IAM role trusted by pods.eks.amazonaws.com and an aws_eks_pod_identity_association binding it to the cert-manager service account. The role ARN is exposed as an output in both modes.",
"description": "Provisions IAM roles and policies for cert-manager on EKS, supporting both IRSA (OIDC federation) and Pod Identity authentication modes with Route53 DNS01 challenge permissions",
"architecture": "An aws_iam_policy resource is always created granting route53:GetChange, route53:ChangeResourceRecordSets, route53:ListResourceRecordSets, and route53:ListHostedZonesByName permissions scoped to the provided hosted zone ARNs. In IRSA mode, the community terraform-aws-modules/iam module creates an aws_iam_role with an OIDC trust policy and attaches the policy via the module's internal aws_iam_role_policy_attachment. In Pod Identity mode, a standalone aws_iam_role is created with a trust policy for pods.eks.amazonaws.com, an aws_iam_role_policy_attachment links the cert-manager policy, and an aws_eks_pod_identity_association binds the role to the cert-manager Kubernetes service account in the cert-manager namespace. The resulting role ARN is surfaced via an output that conditionally selects between the IRSA module output and the Pod Identity resource.",
"features": [
"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 in both identity modes"
"Creates aws_iam_policy granting Route53 DNS01 challenge permissions scoped to specified public and/or private hosted zones",
"Configures IRSA mode using the community iam-role-for-service-accounts module with OIDC provider trust for the cert-manager service account",
"Creates native aws_iam_role trusted by pods.eks.amazonaws.com and aws_eks_pod_identity_association for EKS Pod Identity mode",
"Supports both public and private Route53 hosted zones simultaneously via hosted_zone_public_id and hosted_zone_private_id inputs",
"Includes a moved block for backward-compatible state migration when upgrading from pre-v4.6.0 deployments using IRSA mode"
],
"inputs": [
{
Expand All @@ -111,29 +95,29 @@ resource "example_resource" "this" {
"required": true
},
{
"name": "aws_iam_openid_connect_provider_arn",
"description": "ARN of the AWS IAM OIDC provider. Required when identity_mode is 'irsa'; ignored when identity_mode is 'pod_identity'.",
"name": "hosted_zone_public_id",
"description": "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.",
"required": false
},
{
"name": "identity_mode",
"description": "IAM identity mode: 'irsa' or 'pod_identity'. Default: irsa.",
"name": "aws_iam_openid_connect_provider_arn",
"description": "ARN of the AWS IAM OIDC provider. Required when identity_mode is 'irsa'; ignored when identity_mode is 'pod_identity'.",
"required": false
},
{
"name": "hosted_zone_public_id",
"description": "ID of the public Route53 hosted zone for DNS validation.",
"name": "identity_mode",
"description": "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.",
"required": false
},
{
"name": "hosted_zone_private_id",
"description": "ID of the private Route53 hosted zone for DNS validation.",
"description": "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.",
"required": false
}
],
"outputs": [
"nullplatform_cert_manager_role_arn"
],
"hash": "e4578ab43eee3db215746d060099bc27"
"hash": "be91542baeec9d99fd34d89276b4263a"
}
END_AI_METADATA -->
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/ci-build-workflow-user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The module creates an aws_iam_user named with the cluster_name prefix and genera

```hcl
module "ci-build-workflow-user" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v5.3.0"

cluster_name = "your-cluster-name"
}
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/ecr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The module creates an aws_iam_role named nullplatform-{cluster_name}-application

```hcl
module "ecr" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v5.2.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v5.3.0"

build_workflow_group_name = "your-build-workflow-group-name"
cluster_name = "your-cluster-name"
Expand Down
Loading