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

## [6.6.0](https://github.com/nullplatform/tofu-modules/compare/v6.5.0...v6.6.0) (2026-07-16)


### Features

* **iam:** add cloudwatch IAM module for the logs controller ([#443](https://github.com/nullplatform/tofu-modules/issues/443)) ([35b3b33](https://github.com/nullplatform/tofu-modules/commit/35b3b330ed24d6327132e113dfbeb9a1f831ea4f))

## [6.5.0](https://github.com/nullplatform/tofu-modules/compare/v6.4.0...v6.5.0) (2026-07-16)


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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v6.6.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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v6.6.0"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/cert_manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ An aws_iam_policy resource is always created granting route53:GetChange, route53

```hcl
module "cert_manager" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v6.6.0"

cluster_name = "your-cluster-name"
}
Expand Down
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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v6.6.0"

cluster_name = "your-cluster-name"
}
Expand Down
56 changes: 26 additions & 30 deletions infrastructure/aws/iam/cloudwatch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,36 @@

## Description

Deploys IAM resources that let the nullplatform logs controller (base chart) ship logs and metrics to CloudWatch, supporting both IRSA (OIDC federation) and EKS Pod Identity authentication modes.
Provisions an IAM role and policy for a Kubernetes logs controller to ship logs and metrics to CloudWatch, supporting both IRSA (OIDC federation) and EKS Pod Identity authentication modes

## Architecture

An aws_iam_policy resource named nullplatform_cloudwatch_policy is always created, granting CloudWatch Logs write/describe permissions scoped to the provided log group ARN patterns plus cloudwatch:PutMetricData. In 'irsa' mode, the community iam-role-for-service-accounts module creates an aws_iam_role with an OIDC trust policy for the logs controller service account, attaching the policy via the module's policies map. In 'pod_identity' mode, an aws_iam_role with a pods.eks.amazonaws.com trust principal is created alongside an aws_iam_role_policy_attachment and an aws_eks_pod_identity_association for the logs controller service account. The module outputs the resulting IAM role ARN regardless of which identity mode is active.
The module creates an aws_iam_policy granting CloudWatch Logs and Metrics write permissions, then conditionally wires it to one of two identity paths: when identity_mode is 'irsa', it instantiates the community iam-role-for-service-accounts module which creates an aws_iam_role with an OIDC trust policy bound to the specified service account; when identity_mode is 'pod_identity', it creates an aws_iam_role trusted by pods.eks.amazonaws.com, attaches the policy via aws_iam_role_policy_attachment, and binds the role to the Kubernetes service account through an aws_eks_pod_identity_association. The resulting role ARN is exposed as an output regardless of which path is taken.

## Features

- Creates aws_iam_policy granting CloudWatch Logs (CreateLogGroup/CreateLogStream/PutLogEvents/PutRetentionPolicy) and cloudwatch:PutMetricData permissions
- Scopes log group/stream actions to configurable ARN patterns (defaults to any log group in the account/region; tighten via log_group_arn_patterns)
- Configures IRSA identity mode using the community iam-role-for-service-accounts module with OIDC provider trust for the logs controller service account
- Configures Pod Identity mode by creating an aws_iam_role trusted by pods.eks.amazonaws.com and an aws_eks_pod_identity_association for the logs controller service account
- Service account namespace and name are configurable to match the base chart's namespaces.nullplatformTools
- Creates an aws_iam_policy scoped to CloudWatch log group ARN patterns with write permissions for log groups, log streams, and metric data
- Configures IRSA authentication using the community iam-role-for-service-accounts module with OIDC provider trust for a Kubernetes service account
- Provisions a native EKS Pod Identity IAM role trusted by pods.eks.amazonaws.com with an aws_eks_pod_identity_association binding
- Supports restricting CloudWatch log group access via configurable ARN pattern list
- Outputs a unified role ARN regardless of the identity mode selected

## Basic Usage

```hcl
module "cloudwatch_iam" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cloudwatch?ref=v6.5.0"
module "cloudwatch" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cloudwatch?ref=v6.6.0"

cluster_name = "your-cluster-name"
aws_iam_openid_connect_provider_arn = module.eks.eks_oidc_provider_arn
cluster_name = "your-cluster-name"
}
```

## Using Outputs

```hcl
# Feed the role ARN into the base chart's cloudwatch.serviceAccount.annotations
module "base" {
# ...
cloudwatch_enabled = true
cloudwatch_service_account_annotations = {
"eks.amazonaws.com/role-arn" = module.cloudwatch_iam.nullplatform_cloudwatch_role_arn
}
# Reference outputs in other resources
resource "example_resource" "this" {
example_attribute = module.cloudwatch.nullplatform_cloudwatch_role_arn
}
```

Expand All @@ -47,7 +42,7 @@ module "base" {

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

## Modules

Expand All @@ -71,7 +66,7 @@ module "base" {
| <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 the role belongs to. Used to build the role and policy names. | `string` | n/a | yes |
| <a name="input_identity_mode"></a> [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. Note: switching modes on an existing deployment replaces the IAM role; the logs controller loses permissions during the transition until apply completes. | `string` | `"irsa"` | no |
| <a name="input_log_group_arn_patterns"></a> [log\_group\_arn\_patterns](#input\_log\_group\_arn\_patterns) | Resource ARN patterns the logs controller may write log groups/streams to. Defaults to any CloudWatch log group in the account/region; tighten to a prefix (e.g. arn:aws:logs:\*:\*:log-group:/nullplatform/\*) to restrict. | `list(string)` | <pre>[<br/> "arn:aws:logs:*:*:log-group:*",<br/> "arn:aws:logs:*:*:log-group:*:*"<br/>]</pre> | no |
| <a name="input_log_group_arn_patterns"></a> [log\_group\_arn\_patterns](#input\_log\_group\_arn\_patterns) | Resource ARN patterns the logs controller may write log groups/streams to. Defaults to any CloudWatch log group in the account/region; tighten to a prefix (e.g. arn:aws:logs:*:*:log-group:/nullplatform/*) to restrict. | `list(string)` | <pre>[<br/> "arn:aws:logs:*:*:log-group:*",<br/> "arn:aws:logs:*:*:log-group:*:*"<br/>]</pre> | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Name of the logs controller ServiceAccount that assumes this role. | `string` | `"nullplatform-pod-metadata-reader-sa"` | no |
| <a name="input_service_account_namespace"></a> [service\_account\_namespace](#input\_service\_account\_namespace) | Namespace of the logs controller ServiceAccount. Must match the base chart's namespaces.nullplatformTools. | `string` | `"nullplatform-tools"` | no |

Expand All @@ -85,14 +80,14 @@ module "base" {
<!-- BEGIN_AI_METADATA
{
"name": "cloudwatch",
"description": "Deploys IAM resources that let the nullplatform logs controller ship logs and metrics to CloudWatch, supporting both IRSA (OIDC federation) and EKS Pod Identity authentication modes.",
"architecture": "An aws_iam_policy resource named nullplatform_cloudwatch_policy is always created, granting CloudWatch Logs write/describe permissions scoped to the provided log group ARN patterns plus cloudwatch:PutMetricData. In 'irsa' mode, the community iam-role-for-service-accounts module creates an aws_iam_role with an OIDC trust policy for the logs controller service account. In 'pod_identity' mode, an aws_iam_role with a pods.eks.amazonaws.com trust principal is created alongside an aws_iam_role_policy_attachment and an aws_eks_pod_identity_association for the logs controller service account. The module outputs the resulting IAM role ARN regardless of which identity mode is active.",
"description": "Provisions an IAM role and policy for a Kubernetes logs controller to ship logs and metrics to CloudWatch, supporting both IRSA (OIDC federation) and EKS Pod Identity authentication modes",
"architecture": "The module creates an aws_iam_policy granting CloudWatch Logs and Metrics write permissions, then conditionally wires it to one of two identity paths: when identity_mode is 'irsa', it instantiates the community iam-role-for-service-accounts module which creates an aws_iam_role with an OIDC trust policy bound to the specified service account; when identity_mode is 'pod_identity', it creates an aws_iam_role trusted by pods.eks.amazonaws.com, attaches the policy via aws_iam_role_policy_attachment, and binds the role to the Kubernetes service account through an aws_eks_pod_identity_association. The resulting role ARN is exposed as an output regardless of which path is taken.",
"features": [
"Creates aws_iam_policy granting CloudWatch Logs and cloudwatch:PutMetricData permissions",
"Scopes log group/stream actions to configurable ARN patterns via log_group_arn_patterns",
"Configures IRSA identity mode using the community iam-role-for-service-accounts module with OIDC provider trust for the logs controller service account",
"Configures Pod Identity mode by creating an aws_iam_role trusted by pods.eks.amazonaws.com and an aws_eks_pod_identity_association for the logs controller service account",
"Service account namespace and name are configurable to match the base chart's namespaces.nullplatformTools"
"Creates an aws_iam_policy scoped to CloudWatch log group ARN patterns with write permissions for log groups, log streams, and metric data",
"Configures IRSA authentication using the community iam-role-for-service-accounts module with OIDC provider trust for a Kubernetes service account",
"Provisions a native EKS Pod Identity IAM role trusted by pods.eks.amazonaws.com with an aws_eks_pod_identity_association binding",
"Supports restricting CloudWatch log group access via configurable ARN pattern list",
"Outputs a unified role ARN regardless of the identity mode selected"
],
"inputs": [
{
Expand All @@ -102,7 +97,7 @@ module "base" {
},
{
"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.",
"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. Note: switching modes on an existing deployment replaces the IAM role; the logs controller loses permissions during the transition until apply completes.",
"required": false
},
{
Expand All @@ -122,12 +117,13 @@ module "base" {
},
{
"name": "log_group_arn_patterns",
"description": "Resource ARN patterns the logs controller may write log groups/streams to. Defaults to any CloudWatch log group in the account/region; tighten to a prefix to restrict.",
"description": "Resource ARN patterns the logs controller may write log groups/streams to. Defaults to any CloudWatch log group in the account/region; tighten to a prefix (e.g. arn:aws:logs:*:*:log-group:/nullplatform/*) to restrict.",
"required": false
}
],
"outputs": [
"nullplatform_cloudwatch_role_arn"
]
],
"hash": "413698e33352f93c8e72f05bf40eeb59"
}
END_AI_METADATA -->
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=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v6.6.0"

build_workflow_group_name = "your-build-workflow-group-name"
cluster_name = "your-cluster-name"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/external_dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ An aws_iam_policy resource named nullplatform_external_dns_policy is always crea

```hcl
module "external_dns" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/external_dns?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/external_dns?ref=v6.6.0"

cluster_name = "your-cluster-name"
}
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The module creates an aws_iam_policy resource that allows s3:PutObject and s3:Ge

```hcl
module "s3" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/s3?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/s3?ref=v6.6.0"

bucket = "your-bucket"
build_workflow_group_name = "your-build-workflow-group-name"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/ingress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module creates up to two kubernetes_ingress_v1 resources — one for an inte

```hcl
module "ingress" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/ingress?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/ingress?ref=v6.6.0"

certificate_arn = "your-certificate-arn"
}
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/security/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module uses data sources (aws_eks_cluster, aws_vpc) to derive VPC ID and CID

```hcl
module "security" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/security?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/security?ref=v6.6.0"

cluster_name = "your-cluster-name"
}
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/vpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This module creates a terraform-aws-modules/vpc/aws module resource with DNS hos

```hcl
module "vpc" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/vpc?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/vpc?ref=v6.6.0"

account = "your-account"
organization = "your-organization"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/azure/acr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The module uses the azurerm_container_registry resource to create the container

```hcl
module "acr" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/acr?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/acr?ref=v6.6.0"

containerregistry_name = "your-containerregistry-name"
location = "your-location"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/azure/aks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module wraps the Azure/aks/azurerm community module (version 11.0.0) and use

```hcl
module "aks" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks?ref=v6.6.0"

cluster_name = "your-cluster-name"
location = "your-location"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/azure/aks_route_table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The module uses an azurerm_resources data source to discover the route table cre

```hcl
module "aks_route_table" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks_route_table?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks_route_table?ref=v6.6.0"

node_resource_group = "your-node-resource-group"
subnet_id = "your-subnet-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/azure/dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This module creates an azurerm_dns_zone resource and configures it with the prov

```hcl
module "dns" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/dns?ref=v6.5.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/dns?ref=v6.6.0"

domain_name = "your-domain-name"
resource_group_name = "your-resource-group-name"
Expand Down
Loading