From 808b6d93ea41f4334ad9ca66ea9e8dded88ba25a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:51:00 +0000 Subject: [PATCH 1/2] chore(main): release 8.0.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95c735de..0faef311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [8.0.0](https://github.com/nullplatform/tofu-modules/compare/v7.1.0...v8.0.0) (2026-09-03) + + +### ⚠ BREAKING CHANGES + +* DNS_TYPE, DOMAIN, USE_ACCOUNT_SLUG, SERVICE_TEMPLATE, INITIAL_INGRESS_PATH, and BLUE_GREEN_INGRESS_PATH are no longer set on the agent pod's own env — only on the worker's. Callers relying on those keys being present in the agent pod's configuration.values must move that dependency to the worker. + +### Miscellaneous Chores + +* merge 6.x into main + worker-orchestrator support for services ([#554](https://github.com/nullplatform/tofu-modules/issues/554)) ([34238fd](https://github.com/nullplatform/tofu-modules/commit/34238fd257ee791fdc8e9f79842ed8d921505a1c)) + ## [6.22.1](https://github.com/nullplatform/tofu-modules/compare/v6.22.0...v6.22.1) (2026-09-01) From 16e8fb030628271e8fdb0f31f9a030f48bdb9f3c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 3 Sep 2026 13:57:25 +0000 Subject: [PATCH 2/2] docs: regenerate READMEs for changed modules and update versions --- infrastructure/aws/acm/README.md | 2 +- .../aws_load_balancer_controller/README.md | 2 +- infrastructure/aws/backend/README.md | 2 +- infrastructure/aws/dns/README.md | 2 +- infrastructure/aws/eks/README.md | 2 +- infrastructure/aws/iam/agent/README.md | 2 +- .../README.md | 2 +- infrastructure/aws/iam/cert_manager/README.md | 2 +- .../aws/iam/ci-build-workflow-user/README.md | 2 +- infrastructure/aws/iam/cloudwatch/README.md | 2 +- infrastructure/aws/iam/ecr/README.md | 2 +- infrastructure/aws/iam/external_dns/README.md | 2 +- infrastructure/aws/iam/s3/README.md | 2 +- infrastructure/aws/ingress/README.md | 2 +- infrastructure/aws/security/README.md | 2 +- infrastructure/aws/vpc/README.md | 38 ++- infrastructure/azure/acr/README.md | 2 +- infrastructure/azure/aks/README.md | 54 ++-- .../azure/aks_route_table/README.md | 2 +- infrastructure/azure/dns/README.md | 2 +- infrastructure/azure/iam/README.md | 2 +- infrastructure/azure/private_dns/README.md | 2 +- infrastructure/azure/resource_group/README.md | 2 +- infrastructure/azure/security/README.md | 2 +- infrastructure/azure/vnet/README.md | 2 +- infrastructure/commons/cert_manager/README.md | 143 +++++---- infrastructure/commons/external_dns/README.md | 88 ++++-- infrastructure/commons/istio/README.md | 103 ++----- infrastructure/commons/prometheus/README.md | 68 ++++- .../gcp/artifact-registry/README.md | 53 ++-- infrastructure/gcp/backend/README.md | 50 ++-- infrastructure/gcp/cloud-dns/README.md | 2 +- infrastructure/gcp/cloud-nat/README.md | 2 +- infrastructure/gcp/gke/README.md | 54 ++-- infrastructure/gcp/iam/README.md | 2 +- infrastructure/gcp/security/README.md | 44 +-- infrastructure/gcp/vpc/README.md | 2 +- infrastructure/oci/backend/README.md | 2 +- infrastructure/oci/dns/README.md | 2 +- infrastructure/oci/dynamic_groups/README.md | 2 +- infrastructure/oci/oke/README.md | 2 +- infrastructure/oci/vcn/README.md | 2 +- nullplatform/account/README.md | 2 +- nullplatform/agent/README.md | 279 ++++++++++-------- nullplatform/api_key/README.md | 74 +++-- nullplatform/asset/docker_server/README.md | 40 +-- nullplatform/asset/ecr/README.md | 38 +-- nullplatform/asset/s3/README.md | 34 +-- nullplatform/base/README.md | 148 ++++++---- nullplatform/cloud/aws/cloud/README.md | 2 +- nullplatform/cloud/aws/vpc/README.md | 2 +- nullplatform/cloud/azure/cloud/README.md | 2 +- nullplatform/cloud/gcp/cloud/README.md | 2 +- nullplatform/cloud/oci/cloud/README.md | 2 +- nullplatform/code_repository/README.md | 10 +- .../container_orchestration/aks/README.md | 101 +++++-- .../container_orchestration/eks/README.md | 97 ++++-- .../container_orchestration/gke/README.md | 103 +++++-- .../container_orchestration/oke/README.md | 2 +- nullplatform/dimension/README.md | 2 +- nullplatform/dimension_value/README.md | 2 +- .../identity-access-control/README.md | 2 +- nullplatform/metrics/README.md | 2 +- nullplatform/packaged_service/README.md | 2 +- .../parameter_storage_configuration/README.md | 2 +- .../parameter_storage_definition/README.md | 2 +- .../README.md | 2 +- nullplatform/scope_configuration/README.md | 6 +- nullplatform/scope_definition/README.md | 100 +++---- .../README.md | 59 ++-- nullplatform/service_definition/README.md | 75 +++-- .../README.md | 96 +++--- nullplatform/users/README.md | 2 +- 73 files changed, 1194 insertions(+), 857 deletions(-) diff --git a/infrastructure/aws/acm/README.md b/infrastructure/aws/acm/README.md index f9f91766..65c89522 100644 --- a/infrastructure/aws/acm/README.md +++ b/infrastructure/aws/acm/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v8.0.0" domain_name = "your-domain-name" zone_id = "your-zone-id" diff --git a/infrastructure/aws/aws_load_balancer_controller/README.md b/infrastructure/aws/aws_load_balancer_controller/README.md index bccd8130..c4e3b99d 100644 --- a/infrastructure/aws/aws_load_balancer_controller/README.md +++ b/infrastructure/aws/aws_load_balancer_controller/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v8.0.0" cluster_name = "your-cluster-name" vpc_id = "your-vpc-id" diff --git a/infrastructure/aws/backend/README.md b/infrastructure/aws/backend/README.md index 34b352be..ee9d420a 100644 --- a/infrastructure/aws/backend/README.md +++ b/infrastructure/aws/backend/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v8.0.0" } ``` diff --git a/infrastructure/aws/dns/README.md b/infrastructure/aws/dns/README.md index c8cba7c6..87f5aad3 100644 --- a/infrastructure/aws/dns/README.md +++ b/infrastructure/aws/dns/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v8.0.0" domain_name = "your-domain-name" vpc_id = "your-vpc-id" diff --git a/infrastructure/aws/eks/README.md b/infrastructure/aws/eks/README.md index 9f4d8dfa..6a35a49e 100644 --- a/infrastructure/aws/eks/README.md +++ b/infrastructure/aws/eks/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v8.0.0" aws_subnets_private_ids = "your-aws-subnets-private-ids" aws_vpc_vpc_id = "your-aws-vpc-vpc-id" diff --git a/infrastructure/aws/iam/agent/README.md b/infrastructure/aws/iam/agent/README.md index 05aeaa5b..0d662c61 100644 --- a/infrastructure/aws/iam/agent/README.md +++ b/infrastructure/aws/iam/agent/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v8.0.0" agent_namespace = "your-agent-namespace" aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn" diff --git a/infrastructure/aws/iam/aws_load_balancer_controller_iam/README.md b/infrastructure/aws/iam/aws_load_balancer_controller_iam/README.md index a75f9716..1d100cd7 100644 --- a/infrastructure/aws/iam/aws_load_balancer_controller_iam/README.md +++ b/infrastructure/aws/iam/aws_load_balancer_controller_iam/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v8.0.0" aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn" cluster_name = "your-cluster-name" diff --git a/infrastructure/aws/iam/cert_manager/README.md b/infrastructure/aws/iam/cert_manager/README.md index a94861ee..5ff80b80 100644 --- a/infrastructure/aws/iam/cert_manager/README.md +++ b/infrastructure/aws/iam/cert_manager/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v8.0.0" cluster_name = "your-cluster-name" } diff --git a/infrastructure/aws/iam/ci-build-workflow-user/README.md b/infrastructure/aws/iam/ci-build-workflow-user/README.md index 0964b69b..c8cb10c6 100644 --- a/infrastructure/aws/iam/ci-build-workflow-user/README.md +++ b/infrastructure/aws/iam/ci-build-workflow-user/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v8.0.0" cluster_name = "your-cluster-name" } diff --git a/infrastructure/aws/iam/cloudwatch/README.md b/infrastructure/aws/iam/cloudwatch/README.md index e76378b4..a042e32c 100644 --- a/infrastructure/aws/iam/cloudwatch/README.md +++ b/infrastructure/aws/iam/cloudwatch/README.md @@ -20,7 +20,7 @@ The module creates an aws_iam_policy granting CloudWatch Logs and Metrics write ```hcl module "cloudwatch" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cloudwatch?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cloudwatch?ref=v8.0.0" cluster_name = "your-cluster-name" } diff --git a/infrastructure/aws/iam/ecr/README.md b/infrastructure/aws/iam/ecr/README.md index 0fe74fd7..d03fb34e 100644 --- a/infrastructure/aws/iam/ecr/README.md +++ b/infrastructure/aws/iam/ecr/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v8.0.0" build_workflow_group_name = "your-build-workflow-group-name" cluster_name = "your-cluster-name" diff --git a/infrastructure/aws/iam/external_dns/README.md b/infrastructure/aws/iam/external_dns/README.md index e63a16c0..421edb4c 100644 --- a/infrastructure/aws/iam/external_dns/README.md +++ b/infrastructure/aws/iam/external_dns/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/external_dns?ref=v8.0.0" cluster_name = "your-cluster-name" } diff --git a/infrastructure/aws/iam/s3/README.md b/infrastructure/aws/iam/s3/README.md index ba19b229..e39f5b8c 100644 --- a/infrastructure/aws/iam/s3/README.md +++ b/infrastructure/aws/iam/s3/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/s3?ref=v8.0.0" bucket = "your-bucket" build_workflow_group_name = "your-build-workflow-group-name" diff --git a/infrastructure/aws/ingress/README.md b/infrastructure/aws/ingress/README.md index 03bc8fb8..867a3100 100644 --- a/infrastructure/aws/ingress/README.md +++ b/infrastructure/aws/ingress/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/ingress?ref=v8.0.0" certificate_arn = "your-certificate-arn" } diff --git a/infrastructure/aws/security/README.md b/infrastructure/aws/security/README.md index 99950038..586c52fc 100644 --- a/infrastructure/aws/security/README.md +++ b/infrastructure/aws/security/README.md @@ -22,7 +22,7 @@ The module uses data sources (aws_eks_cluster, aws_vpc) to automatically derive ```hcl module "security" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/security?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/security?ref=v8.0.0" cluster_name = "your-cluster-name" } diff --git a/infrastructure/aws/vpc/README.md b/infrastructure/aws/vpc/README.md index 09b04324..689b71d8 100644 --- a/infrastructure/aws/vpc/README.md +++ b/infrastructure/aws/vpc/README.md @@ -2,27 +2,26 @@ ## Description -Creates an AWS VPC with public and private subnets across multiple availability zones, configured for Kubernetes workloads with NAT gateway for private subnet internet access +Creates an AWS VPC with public and private subnets across multiple availability zones, configured for Kubernetes workloads with NAT gateway support ## Architecture -This module creates a terraform-aws-modules/vpc/aws module resource with DNS hostnames enabled. It provisions public subnets tagged for external load balancers and private subnets tagged for internal load balancers, both tagged for Kubernetes integration. A single NAT gateway is created in a public subnet to enable outbound internet access for resources in private subnets. The VPC name is derived from organization and account variables, and outputs include the VPC ID, subnet IDs, and default security group ID. +The module wraps the terraform-aws-modules/vpc/aws community module to provision an aws_vpc resource along with public and private aws_subnet resources distributed across the specified availability zones. A single aws_nat_gateway is created to provide outbound internet access for private subnets, while an aws_internet_gateway handles public subnet routing. Subnet tags for Kubernetes ELB roles are applied automatically, and outputs expose the vpc_id, subnet IDs, and default security group ID for consumption by downstream modules. ## Features -- Creates VPC with configurable CIDR block and availability zones -- Provisions public subnets with Kubernetes external load balancer tags -- Provisions private subnets with Kubernetes internal load balancer tags -- Configures single NAT gateway for private subnet internet egress -- Enables DNS hostnames for VPC resources -- Tags subnets with nullplatform identifiers for infrastructure management -- Outputs VPC ID, subnet IDs, and default security group for downstream resource integration +- Creates a VPC with configurable CIDR block named after the organization and account +- Provisions public and private subnets across multiple availability zones for high availability +- Deploys a single NAT gateway to provide cost-effective outbound internet access for private subnets +- Applies Kubernetes ELB and internal-ELB subnet tags to enable automatic load balancer subnet discovery +- Applies nullplatform subnet-type tags to distinguish public and private subnets +- Enables DNS hostnames within the VPC to support service discovery and EKS node registration ## Basic Usage ```hcl module "vpc" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/vpc?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/vpc?ref=v8.0.0" account = "your-account" organization = "your-organization" @@ -73,16 +72,15 @@ resource "example_resource" "this" { diff --git a/infrastructure/azure/acr/README.md b/infrastructure/azure/acr/README.md index b50da03c..a4cd8829 100644 --- a/infrastructure/azure/acr/README.md +++ b/infrastructure/azure/acr/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/acr?ref=v8.0.0" containerregistry_name = "your-containerregistry-name" location = "your-location" diff --git a/infrastructure/azure/aks/README.md b/infrastructure/azure/aks/README.md index d9f06da7..d8b80b7f 100644 --- a/infrastructure/azure/aks/README.md +++ b/infrastructure/azure/aks/README.md @@ -2,27 +2,27 @@ ## Description -Deploys an Azure Kubernetes Service (AKS) cluster with a system node pool and an autoscaling user node pool using the official Azure/aks/azurerm Terraform module +Deploys an Azure Kubernetes Service (AKS) cluster with configurable system and user node pools, OIDC/workload identity, Azure RBAC integration, and optional ACR attachment using the Azure/aks/azurerm upstream module ## Architecture -The module wraps the Azure/aks/azurerm community module (version 11.0.0) and reads the current client config via azurerm_client_config to inject the tenant ID for AAD RBAC. It wires the provided vnet_subnet_id into both the system pool (agents_size, agents_count, agents_availability_zones) and a separate user node_pool entry with auto-scaling enabled, assigning Network Contributor role to all required subnets via network_contributor_role_assigned_subnet_ids. Optional ACR integration is handled through attached_acr_id_map, which conditionally maps acr_id based on the attach_acr flag, and OIDC/workload identity is always enabled on the control plane. +The module wraps the Azure/aks/azurerm community module (version 11.0.0) and wires all inputs into it as a single module block. A data.azurerm_client_config resource is used to resolve the current tenant ID for AAD/RBAC configuration. The module creates a system node pool via agents_* parameters and a separate autoscaling user node pool via the node_pools map, both attached to the provided vnet_subnet_id. Network Contributor role assignments are applied to the node subnet and any additional subnets, and an optional AcrPull role binding is conditionally created based on attach_acr and acr_id inputs. ## Features -- Deploys AKS cluster with OIDC issuer and workload identity enabled for pod-level Azure authentication -- Configures a fixed-size system node pool and a separate autoscaling user node pool with configurable min/max counts -- Grants Network Contributor role on the node subnet and any additional subnets required for internal load balancers -- Attaches an Azure Container Registry with AcrPull role when acr_id is provided -- Supports availability zone distribution for both system and user node pools +- Creates AKS cluster with a fixed system node pool and an autoscaling user node pool across configurable availability zones +- Enables OIDC issuer and workload identity on the cluster for Kubernetes service account federation +- Configures Azure AD RBAC integration with tenant-scoped admin group object IDs and optional Azure RBAC delegation +- Attaches Azure Container Registry with AcrPull role assignment when acr_id is provided +- Assigns Network Contributor role to the node subnet and any additional subnets required for internal load balancer provisioning - Exposes cluster credentials and OIDC issuer URL as outputs for downstream Kubernetes provider configuration -- Allows optional private cluster mode and API server IP allowlisting for network security hardening +- Supports private cluster mode and API server authorized IP range restrictions ## Basic Usage ```hcl module "aks" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks?ref=v8.0.0" cluster_name = "your-cluster-name" location = "your-location" @@ -74,11 +74,14 @@ resource "example_resource" "this" { |------|-------------|------|---------|:--------:| | [acr\_id](#input\_acr\_id) | The ID of the Azure Container Registry. If provided, AKS will be granted AcrPull role to pull images. | `string` | `null` | no | | [additional\_network\_contributor\_subnet\_ids](#input\_additional\_network\_contributor\_subnet\_ids) | Extra subnet IDs, keyed by an arbitrary stable name, where the cluster identity also needs Network Contributor. The node subnet is granted automatically; add an entry for any other subnet the cloud-provider must write into -- typically the one an internal load balancer is pinned to via service.beta.kubernetes.io/azure-load-balancer-internal-subnet, which otherwise fails to provision with a 403 on virtualNetworks/subnets/read. | `map(string)` | `{}` | no | +| [admin\_group\_object\_ids](#input\_admin\_group\_object\_ids) | Entra ID group object IDs whose members get cluster-admin through Kubernetes RBAC. The alternative to azure\_rbac\_enabled when authorization should stay in-cluster. | `list(string)` | `null` | no | | [attach\_acr](#input\_attach\_acr) | Whether to grant AKS the AcrPull role on acr\_id. Null (default) preserves the legacy behaviour of attaching whenever acr\_id is non-null. Set to true for a greenfield single-apply where acr\_id is known only after apply (keeps the for\_each key set plan-stable); set to false to disable. | `bool` | `null` | no | | [authorized\_ip\_ranges](#input\_authorized\_ip\_ranges) | The set of authorized IP ranges allowed to access the Kubernetes API server | `set(string)` | `null` | no | +| [azure\_rbac\_enabled](#input\_azure\_rbac\_enabled) | Whether Kubernetes authorization is delegated to Azure RBAC, so cluster access is granted with Azure role assignments such as 'Azure Kubernetes Service RBAC Cluster Admin'. Defaults to false, which keeps authorization inside Kubernetes RBAC. | `bool` | `false` | no | | [cluster\_name](#input\_cluster\_name) | The name of the AKS cluster | `string` | n/a | yes | | [environment](#input\_environment) | The environment name used for tagging and naming purposes | `string` | `"nullplatform"` | no | | [kubernetes\_version](#input\_kubernetes\_version) | The version of Kubernetes to use for the AKS cluster | `string` | `"1.32.7"` | no | +| [local\_account\_disabled](#input\_local\_account\_disabled) | Whether to disable the AKS local (certificate-based) admin accounts. Null (default) leaves the Azure default, which keeps them enabled. When true, Entra ID becomes the only way into the API server, so an authorization path must be configured as well — see azure\_rbac\_enabled and admin\_group\_object\_ids. | `bool` | `null` | no | | [location](#input\_location) | The Azure region where the AKS cluster will be deployed (e.g., eastus, westus2) | `string` | n/a | yes | | [node\_pool\_zones](#input\_node\_pool\_zones) | Availability zones for the user node pool, e.g. ["1", "2", "3"].
Null (default) leaves the pool unzoned. Set it deliberately on a live
cluster: Azure treats a pool's zones as immutable, and upstream rotates the
pool through `temporary_name_for_rotation` to honour the change. | `set(string)` | `null` | no | | [prefix](#input\_prefix) | The prefix for resources created by the AKS module | `string` | `"aks"` | no | @@ -113,16 +116,16 @@ resource "example_resource" "this" { diff --git a/infrastructure/azure/aks_route_table/README.md b/infrastructure/azure/aks_route_table/README.md index 33c7781a..60ee682a 100644 --- a/infrastructure/azure/aks_route_table/README.md +++ b/infrastructure/azure/aks_route_table/README.md @@ -19,7 +19,7 @@ The module uses an azurerm_resources data source to discover the AKS-managed rou ```hcl module "aks_route_table" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks_route_table?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/aks_route_table?ref=v8.0.0" node_resource_group = "your-node-resource-group" subnet_id = "your-subnet-id" diff --git a/infrastructure/azure/dns/README.md b/infrastructure/azure/dns/README.md index fc0fc2d0..c1530b22 100644 --- a/infrastructure/azure/dns/README.md +++ b/infrastructure/azure/dns/README.md @@ -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=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/dns?ref=v8.0.0" domain_name = "your-domain-name" resource_group_name = "your-resource-group-name" diff --git a/infrastructure/azure/iam/README.md b/infrastructure/azure/iam/README.md index 505a5d98..de8fc3d5 100644 --- a/infrastructure/azure/iam/README.md +++ b/infrastructure/azure/iam/README.md @@ -21,7 +21,7 @@ The module creates an azurerm_user_assigned_identity resource in the specified r ```hcl module "iam" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/iam?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/iam?ref=v8.0.0" location = "your-location" name = "your-name" diff --git a/infrastructure/azure/private_dns/README.md b/infrastructure/azure/private_dns/README.md index b5b2c7be..af722cbd 100644 --- a/infrastructure/azure/private_dns/README.md +++ b/infrastructure/azure/private_dns/README.md @@ -18,7 +18,7 @@ This module creates an azurerm_private_dns_zone resource and optionally multiple ```hcl module "private_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/private_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/private_dns?ref=v8.0.0" domain_name = "your-domain-name" resource_group_name = "your-resource-group-name" diff --git a/infrastructure/azure/resource_group/README.md b/infrastructure/azure/resource_group/README.md index 0906096a..35c3e4e5 100644 --- a/infrastructure/azure/resource_group/README.md +++ b/infrastructure/azure/resource_group/README.md @@ -18,7 +18,7 @@ This module creates an azurerm_resource_group resource and outputs its name and ```hcl module "resource_group" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/resource_group?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/resource_group?ref=v8.0.0" location = "your-location" resource_group_name = "your-resource-group-name" diff --git a/infrastructure/azure/security/README.md b/infrastructure/azure/security/README.md index 7cfb4076..6dbaf755 100644 --- a/infrastructure/azure/security/README.md +++ b/infrastructure/azure/security/README.md @@ -21,7 +21,7 @@ The module uses azurerm_kubernetes_cluster and azurerm_virtual_network data sour ```hcl module "security" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/security?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/security?ref=v8.0.0" cluster_name = "your-cluster-name" resource_group_name = "your-resource-group-name" diff --git a/infrastructure/azure/vnet/README.md b/infrastructure/azure/vnet/README.md index 89161f6a..f7f41d8a 100644 --- a/infrastructure/azure/vnet/README.md +++ b/infrastructure/azure/vnet/README.md @@ -18,7 +18,7 @@ This module creates an Azure virtual network using the azurerm provider and conf ```hcl module "vnet" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/vnet?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/azure/vnet?ref=v8.0.0" address_space = "your-address-space" location = "your-location" diff --git a/infrastructure/commons/cert_manager/README.md b/infrastructure/commons/cert_manager/README.md index d212a57c..5b790c6e 100644 --- a/infrastructure/commons/cert_manager/README.md +++ b/infrastructure/commons/cert_manager/README.md @@ -2,55 +2,57 @@ ## Description -Deploys cert-manager and its configuration Helm charts on Kubernetes with multi-cloud DNS01 solver support for GCP, Azure, AWS, Cloudflare, and OCI +Deploys cert-manager and its cloud-provider-specific configuration via Helm onto a Kubernetes cluster, supporting DNS01 challenge solvers across GCP, AWS, Azure, Cloudflare, and OCI ## Architecture -Two primary helm_release resources are created: cert-manager from the Jetstack chart repository and nullplatform-cert-manager-config from the nullplatform chart repository, with the config chart depending on the base cert-manager release. A third conditional helm_release for cert-manager-webhook-oci is created only when cloud_provider is 'oci'. The cert_manager_values local constructs the Helm values dynamically, merging base service account annotations with provider-specific annotations (GCP Workload Identity, AWS IRSA role ARN, Azure Workload Identity client ID, or OCI workload identity principal) based on cloud_provider and aws_identity_mode. Template files cert_manager_default_values and cert_manager_provider_values are rendered via templatefile() using common_context and provider_context locals and passed as values to the config chart. +Two core helm_release resources are created: cert-manager from charts.jetstack.io and nullplatform-cert-manager-config from nullplatform's Helm registry, with the config chart depending on the cert-manager release. A conditional third helm_release (cert_manager_webhook_oci) is created only when cloud_provider is 'oci'. Provider-specific service account annotations are constructed in locals by merging base_annotations with provider-keyed annotation maps, and provider-specific Helm values are rendered from templatefiles keyed by var.cloud_provider and merged into the cert-manager-config release. ## Features - Deploys cert-manager Helm chart with CRDs enabled and DNS01 recursive nameserver configuration -- Deploys nullplatform-cert-manager-config Helm chart with provider-specific DNS01 solver templates rendered via templatefile() -- Configures cert-manager Kubernetes service account annotations for GCP Workload Identity, AWS IRSA, Azure Workload Identity, and OCI workload identity -- Deploys cert-manager-webhook-oci Helm chart conditionally when cloud_provider is set to oci -- Supports AWS Pod Identity mode that omits IRSA role annotation for EKS Pod Identity agent-based credential injection -- Supports Azure Service Principal authentication when workload identity is disabled via azure_workload_identity_enabled -- Merges provider-specific pod labels for Azure Workload Identity use annotation on cert-manager pods +- Renders provider-specific Helm value templates for GCP, AWS, Azure, Cloudflare, and OCI DNS01 solvers +- Configures cert-manager service account annotations dynamically per cloud provider (GKE Workload Identity, IRSA, Azure Workload Identity, OCI) +- Deploys OCI webhook Helm chart conditionally when cloud_provider is set to oci +- Supports both IRSA and EKS Pod Identity authentication modes for AWS +- Supports Azure Workload Identity and Service Principal authentication modes for Azure DNS solver +- Pins cert-manager chart version explicitly, rejecting empty or moving references like latest, main, or master ## Basic Usage ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" - account_slug = "your-account-slug" - cloud_provider = "your-cloud-provider" - hosted_zone_name = "your-hosted-zone-name" - private_domain_name = "your-private-domain-name" + account_slug = "your-account-slug" + cert_manager_version = "your-cert-manager-version" + cloud_provider = "your-cloud-provider" + hosted_zone_name = "your-hosted-zone-name" + private_domain_name = "your-private-domain-name" } ``` -### Usage with GCP Provider +### Usage with GCP DNS01 Solver ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" - - account_slug = "your-account-slug" - cloud_provider = "gcp" - gcp_sa_email = "your-gcp-sa-email" # Required when cloud_provider = "gcp" - hosted_zone_name = "your-hosted-zone-name" - private_domain_name = "your-private-domain-name" - project_id = "your-project-id" # Required when cloud_provider = "gcp" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" + + account_slug = "your-account-slug" + cert_manager_version = "your-cert-manager-version" + cloud_provider = "gcp" + gcp_sa_email = "your-gcp-sa-email" # Required when cloud_provider = "gcp" + hosted_zone_name = "your-hosted-zone-name" + private_domain_name = "your-private-domain-name" + project_id = "your-project-id" # Required when cloud_provider = "gcp" } ``` -### Usage with Azure Provider +### Usage with Azure DNS01 Solver ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" account_slug = "your-account-slug" azure_client_id = "your-azure-client-id" # Required when cloud_provider = "azure" @@ -58,19 +60,21 @@ module "cert_manager" { azure_resource_group_name = "your-azure-resource-group-name" # Required when cloud_provider = "azure" azure_subscription_id = "your-azure-subscription-id" # Required when cloud_provider = "azure" azure_tenant_id = "your-azure-tenant-id" # Required when cloud_provider = "azure" + cert_manager_version = "your-cert-manager-version" cloud_provider = "azure" hosted_zone_name = "your-hosted-zone-name" private_domain_name = "your-private-domain-name" } ``` -### Usage with Cloudflare Provider +### Usage with Cloudflare DNS01 Solver ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" account_slug = "your-account-slug" + cert_manager_version = "your-cert-manager-version" cloud_provider = "cloudflare" cloudflare_secret_name = "your-cloudflare-secret-name" # Required when cloud_provider = "cloudflare" cloudflare_token = "your-cloudflare-token" # Required when cloud_provider = "cloudflare" @@ -79,37 +83,50 @@ module "cert_manager" { } ``` -### Usage with AWS Provider +### Usage with AWS DNS01 Solver ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" - - account_slug = "your-account-slug" - aws_identity_mode = "your-aws-identity-mode" # Required when cloud_provider = "aws" - aws_region = "your-aws-region" # Required when cloud_provider = "aws" - aws_sa_arn = "your-aws-sa-arn" # Required when cloud_provider = "aws" - cloud_provider = "aws" - hosted_zone_name = "your-hosted-zone-name" - private_domain_name = "your-private-domain-name" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" + + account_slug = "your-account-slug" + aws_region = "your-aws-region" # Required when cloud_provider = "aws" + aws_sa_arn = "your-aws-sa-arn" # Required when cloud_provider = "aws" + cert_manager_version = "your-cert-manager-version" + cloud_provider = "aws" + hosted_zone_name = "your-hosted-zone-name" + private_domain_name = "your-private-domain-name" } ``` -### Usage with OCI Provider +### Usage with OCI DNS01 Solver ```hcl module "cert_manager" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v7.1.0" - - account_slug = "your-account-slug" - cert_manager_webhook_oci_namespace = "your-cert-manager-webhook-oci-namespace" # Required when cloud_provider = "oci" - cert_manager_webhook_oci_version = "your-cert-manager-webhook-oci-version" # Required when cloud_provider = "oci" - cloud_provider = "oci" - hosted_zone_name = "your-hosted-zone-name" - oci_compartment_ocid = "your-oci-compartment-ocid" # Required when cloud_provider = "oci" - oci_region = "your-oci-region" # Required when cloud_provider = "oci" - oci_sa_ocid = "your-oci-sa-ocid" # Required when cloud_provider = "oci" - private_domain_name = "your-private-domain-name" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" + + account_slug = "your-account-slug" + cert_manager_version = "your-cert-manager-version" + cloud_provider = "oci" + hosted_zone_name = "your-hosted-zone-name" + oci_compartment_ocid = "your-oci-compartment-ocid" # Required when cloud_provider = "oci" + oci_region = "your-oci-region" # Required when cloud_provider = "oci" + oci_sa_ocid = "your-oci-sa-ocid" # Required when cloud_provider = "oci" + private_domain_name = "your-private-domain-name" +} +``` + +### Usage with cert-manager Version Pin + +```hcl +module "cert_manager" { + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/cert_manager?ref=v8.0.0" + + account_slug = "your-account-slug" + cert_manager_version = "fixed semver string" + cloud_provider = "your-cloud-provider" + hosted_zone_name = "your-hosted-zone-name" + private_domain_name = "your-private-domain-name" } ``` @@ -163,7 +180,7 @@ resource "example_resource" "this" { | [azure\_workload\_identity\_enabled](#input\_azure\_workload\_identity\_enabled) | Enable Workload Identity for Azure DNS solver. When false, Service Principal auth is used and azure\_client\_secret is required. | `bool` | `true` | no | | [cert\_manager\_config\_version](#input\_cert\_manager\_config\_version) | The version of the cert-manager configuration Helm chart | `string` | `"2.35.0"` | no | | [cert\_manager\_namespace](#input\_cert\_manager\_namespace) | The Kubernetes namespace where cert-manager will be deployed | `string` | `"cert-manager"` | no | -| [cert\_manager\_version](#input\_cert\_manager\_version) | The version of cert-manager Helm chart to deploy | `string` | `"1.18.2"` | no | +| [cert\_manager\_version](#input\_cert\_manager\_version) | No default: every install pins this deliberately — see VERSIONS.md. The version of cert-manager Helm chart to deploy. Was declared but never wired to the helm\_release, so installs tracked whatever the chart repository served; the default is the version that resolved to as of 2026-08-27, which keeps behaviour unchanged while removing the drift. | `string` | n/a | yes | | [cert\_manager\_webhook\_oci\_namespace](#input\_cert\_manager\_webhook\_oci\_namespace) | Kubernetes namespace where the cert-manager OCI webhook is deployed | `string` | `"cert-manager"` | no | | [cert\_manager\_webhook\_oci\_version](#input\_cert\_manager\_webhook\_oci\_version) | Helm chart version for the cert-manager OCI webhook | `string` | `"1.4.1"` | no | | [cloud\_provider](#input\_cloud\_provider) | The cloud provider to use: gcp, azure, aws, cloudflare, or oci | `string` | n/a | yes | @@ -181,16 +198,16 @@ resource "example_resource" "this" { diff --git a/infrastructure/commons/external_dns/README.md b/infrastructure/commons/external_dns/README.md index 6537ff1e..e43f447c 100644 --- a/infrastructure/commons/external_dns/README.md +++ b/infrastructure/commons/external_dns/README.md @@ -2,27 +2,27 @@ ## Description -Deploys ExternalDNS via Helm on Kubernetes with multi-provider DNS support for Cloudflare, AWS Route53, OCI, Azure Public DNS, and Azure Private DNS +Deploys ExternalDNS via a Helm chart on Kubernetes with multi-provider DNS support including Cloudflare, AWS Route53, OCI, Azure (public and private), and Google Cloud DNS ## Architecture -The module creates an optional kubernetes_namespace_v1 resource when create_namespace is true, then deploys a helm_release resource for the external-dns chart using provider-specific values merged from locals. Provider-specific kubernetes_secret_v1 resources are created for Cloudflare API tokens, OCI config files, and Azure config files, and are referenced as explicit dependencies of the helm_release. The external_dns_values local merges a base_config (domainFilters, policy, txtOwnerId, sources) with a provider-specific config block selected by dns_provider_name, which controls the serviceAccount annotations (IRSA or Pod Identity for AWS, Workload Identity for Azure), extraArgs (zone filters, OCI compartment), extraVolumes/extraVolumeMounts (OCI and Azure secrets), and environment variables. +The module creates an optional kubernetes_namespace_v1 resource when create_namespace is true, then deploys a helm_release resource using the official external-dns Helm chart from kubernetes-sigs. Provider-specific configuration is assembled in locals.tf by merging a base_config with a provider-specific config block (cloudflare_config, route53_config, oci_config, azure_config, or google_config) selected via var.dns_provider_name. Provider secrets are mounted as kubernetes_secret_v1 resources (for Cloudflare, OCI, and Azure) and the helm_release depends on those secrets before rendering the final yamlencode values block. ## Features -- Deploys ExternalDNS Helm chart with provider-specific configuration for Cloudflare, AWS Route53, OCI, Azure Public DNS, and Azure Private DNS -- Configures AWS IRSA or EKS Pod Identity for Route53 access by conditionally annotating the Kubernetes ServiceAccount with the IAM role ARN -- Mounts OCI config and Azure config as Kubernetes secrets into the ExternalDNS pod via extraVolumes and extraVolumeMounts -- Supports Azure Workload Identity by annotating the ServiceAccount with the client ID and labeling pods with the workload identity use label -- Creates optional Kubernetes namespace for ExternalDNS to support single or multi-instance deployments in the same cluster -- Applies label-filter and zone-id-filter extraArgs for AWS Route53 to scope ExternalDNS to specific hosted zones or resource labels -- Configures DNS record management policy (sync, create-only, upsert-only) and TXT registry owner ID for record ownership tracking +- Deploys ExternalDNS Helm chart with configurable version and namespace into Kubernetes +- Supports six DNS providers: Cloudflare, AWS Route53, OCI, Azure Public DNS, Azure Private DNS, and Google Cloud DNS +- Configures AWS IRSA or EKS Pod Identity annotation on the Kubernetes ServiceAccount for Route53 access +- Mounts provider-specific Kubernetes secrets for Cloudflare API token, OCI config, and Azure credentials +- Configures Azure Workload Identity or Service Principal authentication for Azure DNS providers +- Wires GCP Workload Identity via iam.gke.io/gcp-service-account annotation on the Kubernetes ServiceAccount +- Supports label-based filtering of Kubernetes resources processed by ExternalDNS with automatic zone-type defaulting ## Basic Usage ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" dns_provider_name = "your-dns-provider-name" domain_filters = "your-domain-filters" @@ -33,7 +33,7 @@ module "external_dns" { ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" cloudflare_token = "your-cloudflare-token" # Required when dns_provider_name = "cloudflare" dns_provider_name = "cloudflare" @@ -45,7 +45,7 @@ module "external_dns" { ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" aws_iam_role_arn = "your-aws-iam-role-arn" # Required when dns_provider_name = "aws" aws_identity_mode = "your-aws-identity-mode" # Required when dns_provider_name = "aws" @@ -61,7 +61,7 @@ module "external_dns" { ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" dns_provider_name = "oci" domain_filters = "your-domain-filters" @@ -77,9 +77,10 @@ module "external_dns" { ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" azure_client_id = "your-azure-client-id" # Required when dns_provider_name = "azure" + azure_client_secret = "your-azure-client-secret" # Required when dns_provider_name = "azure" azure_federated_credential_id = "your-azure-federated-credential-id" # Required when dns_provider_name = "azure" azure_resource_group = "your-azure-resource-group" # Required when dns_provider_name = "azure" azure_subscription_id = "your-azure-subscription-id" # Required when dns_provider_name = "azure" @@ -94,9 +95,10 @@ module "external_dns" { ```hcl module "external_dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" azure_client_id = "your-azure-client-id" # Required when dns_provider_name = "azure-private-dns" + azure_client_secret = "your-azure-client-secret" # Required when dns_provider_name = "azure-private-dns" azure_federated_credential_id = "your-azure-federated-credential-id" # Required when dns_provider_name = "azure-private-dns" azure_resource_group = "your-azure-resource-group" # Required when dns_provider_name = "azure-private-dns" azure_subscription_id = "your-azure-subscription-id" # Required when dns_provider_name = "azure-private-dns" @@ -107,6 +109,20 @@ module "external_dns" { } ``` +### Usage with Google Cloud DNS + +```hcl +module "external_dns" { + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/external_dns?ref=v8.0.0" + + dns_provider_name = "google" + domain_filters = "your-domain-filters" + gcp_project_id = "your-gcp-project-id" # Required when dns_provider_name = "google" + gcp_service_account_email = "your-gcp-service-account-email" # Required when dns_provider_name = "google" + gcp_service_account_name = "your-gcp-service-account-name" # Required when dns_provider_name = "google" +} +``` + ## Using Outputs ```hcl @@ -162,6 +178,9 @@ resource "example_resource" "this" { | [domain\_filters](#input\_domain\_filters) | The domain filter to limit ExternalDNS to manage DNS records only for specific domains | `string` | n/a | yes | | [external\_dns\_namespace](#input\_external\_dns\_namespace) | The Kubernetes namespace where ExternalDNS will be deployed | `string` | `"external-dns"` | no | | [external\_dns\_version](#input\_external\_dns\_version) | The version of ExternalDNS Helm chart to deploy | `string` | `"1.19.0"` | no | +| [gcp\_project\_id](#input\_gcp\_project\_id) | The GCP project ID where the Cloud DNS zones are located (required when dns\_provider\_name is 'google') | `string` | `""` | no | +| [gcp\_service\_account\_email](#input\_gcp\_service\_account\_email) | Email of the GCP service account bound via Workload Identity for Cloud DNS access (required when dns\_provider\_name is 'google'). Create the service account and the Workload Identity binding outside this module (e.g. with infrastructure/gcp/iam) and pass its email here. | `string` | `""` | no | +| [gcp\_service\_account\_name](#input\_gcp\_service\_account\_name) | The Kubernetes service account name for GCP Workload Identity | `string` | `"external-dns"` | no | | [label\_filter](#input\_label\_filter) | Kubernetes label selector to filter resources processed by ExternalDNS. Defaults to 'dns/zone-type=' when zone\_type is set. Pass an explicit value to override, or an empty string to disable filtering. | `string` | `null` | no | | [oci\_compartment\_ocid](#input\_oci\_compartment\_ocid) | The OCI compartment OCID where the DNS zones are located (required when dns\_provider\_name is 'oci') | `string` | `""` | no | | [oci\_region](#input\_oci\_region) | The OCI region for workload identity configuration (required when dns\_provider\_name is 'oci') | `string` | `""` | no | @@ -173,22 +192,22 @@ resource "example_resource" "this" { | [txt\_owner\_id](#input\_txt\_owner\_id) | The TXT owner ID used by ExternalDNS to identify DNS records it manages | `string` | `"external_dns"` | no | | [type](#input\_type) | Determines whether the external-dns deployment is public or private | `string` | `"public"` | no | | [zone\_id\_filter](#input\_zone\_id\_filter) | The Route53 public or private hosted zone ID for ExternalDNS to manage (required when dns\_provider\_name is 'aws') | `string` | `""` | no | -| [zone\_type](#input\_zone\_type) | The Route53 hosted zone type for ExternalDNS to manage (public or private) | `string` | `""` | no | +| [zone\_type](#input\_zone\_type) | The DNS zone type/visibility for ExternalDNS to manage (public or private). Used by the 'aws' (--aws-zone-type) and 'google' (--google-zone-visibility) providers. | `string` | `""` | no | diff --git a/infrastructure/commons/istio/README.md b/infrastructure/commons/istio/README.md index be60678b..5db74f00 100644 --- a/infrastructure/commons/istio/README.md +++ b/infrastructure/commons/istio/README.md @@ -2,26 +2,26 @@ ## Description -Deploys a full Istio service mesh stack (istio-base, istiod, and istio-ingressgateway) on Kubernetes using sequenced Helm releases with cloud-provider-specific LoadBalancer annotations +Deploys Istio service mesh onto a Kubernetes cluster using Helm, installing both the istio-base CRDs and the istiod control plane with configurable high-availability replica settings ## Architecture -Three helm_release resources are created in a strict dependency chain: istio-base is deployed first, istiod depends on istio-base and configures pilot.replicaCount and pilot.autoscaleMin via dynamic set blocks using var.istiod_replicas, and istio-ingressgateway depends on istiod and receives its configuration through a templatefile-rendered values YAML stored in locals.helm_values. The template injects service type, port mappings, HTTP2 settings, and cloud-provider-specific annotations (such as OCI subnet IDs) into the gateway Helm chart values. +The module creates two helm_release resources in sequence: first istio-base (which installs Istio CRDs and cluster-wide resources), then istiod (which depends on istio-base and installs the Istio control plane). The istiod helm_release uses set blocks to configure both pilot.replicaCount and pilot.autoscaleMin from the istiod_replicas variable, ensuring the HPA cannot scale below the specified floor. Both releases target the same Kubernetes namespace, which is created automatically if it does not exist. ## Features -- Deploys istio-base, istiod, and istio-ingressgateway Helm charts in dependency order with atomic and cleanup-on-fail guarantees -- Configures istiod HA by setting both pilot.replicaCount and pilot.autoscaleMin to prevent the HPA from scaling below the desired replica floor -- Renders cloud-provider-specific LoadBalancer annotations for AWS, OCI, Azure, and GCP via a templatefile-based Helm values injection -- Exposes configurable HTTPS and optional HTTP2 ports with independently tunable service and container target ports -- Supports OCI-specific LoadBalancer subnet assignment via oci_load_balancer_subnet_ids annotation injection -- Allows namespace, Helm repository URL, and individual chart versions to be overridden independently for each Istio component +- Installs istio-base Helm chart providing Istio CRDs and cluster-scoped RBAC resources +- Deploys istiod Helm chart as the Istio control plane with explicit dependency on istio-base +- Configures high-availability istiod replicas by setting both pilot.replicaCount and pilot.autoscaleMin to prevent HPA from scaling back to 1 +- Enforces atomic Helm deployments with automatic cleanup on failure for both releases +- Supports configurable Helm chart versions for independent upgrades of istio-base and istiod +- Creates the target Kubernetes namespace automatically if it does not already exist ## Basic Usage ```hcl module "istio" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/istio?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/istio?ref=v8.0.0" } ``` @@ -46,50 +46,37 @@ resource "example_resource" "this" { | Name | Version | |------|---------| | [helm](#provider\_helm) | 3.1.1 | -| [terraform](#provider\_terraform) | n/a | ## Resources | Name | Type | |------|------| | [helm_release.istio_base](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [helm_release.istio_ingressgateway](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.istiod](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [terraform_data.provider_validation](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cloud\_provider](#input\_cloud\_provider) | The cloud provider where the cluster is running. Used to inject provider-specific LoadBalancer annotations (e.g. oci). Leave empty for generic/on-prem clusters. | `string` | `""` | no | -| [enable\_http2](#input\_enable\_http2) | Whether to expose the HTTP2 (port 80) service | `bool` | `false` | no | -| [http2\_port](#input\_http2\_port) | The external service port for HTTP2 when enabled. | `number` | `80` | no | -| [http2\_target\_port](#input\_http2\_target\_port) | The container target port for HTTP2 when enabled | `number` | `80` | no | -| [https\_port](#input\_https\_port) | The external HTTPS service port | `number` | `443` | no | -| [https\_target\_port](#input\_https\_target\_port) | The container target port for HTTPS | `number` | `8443` | no | | [istio\_base\_version](#input\_istio\_base\_version) | Helm chart version for the istio-base component | `string` | `"1.27.1"` | no | -| [istio\_ingressgateway\_version](#input\_istio\_ingressgateway\_version) | Helm chart version for the Istio ingress gateway | `string` | `"1.27.1"` | no | | [istiod\_replicas](#input\_istiod\_replicas) | Number of istiod replicas. Set to 2+ to avoid PDB blocking node drains. Applied to both pilot.replicaCount and pilot.autoscaleMin to prevent the HPA from scaling back to 1. | `number` | `2` | no | | [istiod\_version](#input\_istiod\_version) | Helm chart version for istiod (Istio control plane) | `string` | `"1.27.1"` | no | -| [namespace](#input\_namespace) | The Kubernetes namespace where gateway will be installed. | `string` | `"istio-system"` | no | -| [oci\_load\_balancer\_subnet\_ids](#input\_oci\_load\_balancer\_subnet\_ids) | List of OCI subnet OCIDs for the LoadBalancer Service (required when cloud\_provider is 'oci') | `list(string)` | `[]` | no | +| [namespace](#input\_namespace) | The Kubernetes namespace where Istio will be installed. | `string` | `"istio-system"` | no | | [repository](#input\_repository) | The Helm repository URL (e.g., https://istio-release.storage.googleapis.com/charts). | `string` | `"https://istio-release.storage.googleapis.com/charts"` | no | -| [service\_type](#input\_service\_type) | The Kubernetes service type for the Istio ingress gateway | `string` | `"LoadBalancer"` | no | -| [status\_port](#input\_status\_port) | The status port used (status-port) | `number` | `15021` | no | diff --git a/infrastructure/commons/prometheus/README.md b/infrastructure/commons/prometheus/README.md index 734357a0..0e622493 100644 --- a/infrastructure/commons/prometheus/README.md +++ b/infrastructure/commons/prometheus/README.md @@ -2,23 +2,57 @@ ## Description -Deploys Prometheus using Helm chart in a specified Kubernetes namespace +Deploys Prometheus monitoring stack into a Kubernetes cluster using the prometheus-community Helm chart with a pinned version and templated values ## Architecture -This module creates a helm_release resource to deploy the Prometheus chart from the prometheus-community repository, and uses a templatefile to populate the prometheus_values template with the nullplatform_port variable, the resulting values are then passed to the helm_release resource, which creates the necessary Kubernetes resources, including deployments, services, and pods, in the specified namespace +The module renders a YAML values file via templatefile() in locals.tf, injecting the nullplatform_port variable into a prometheus_values.tmpl.yaml template. A single helm_release resource named 'prometheus' is created targeting the prometheus-community/prometheus chart at the specified pinned version, deploying into the configured Kubernetes namespace. The rendered template values are passed directly to the helm_release values argument, and Helm lifecycle options such as atomic, cleanup_on_fail, and wait_for_jobs are hardcoded to enforce reliable deployment behavior. ## Features -- Deploys Prometheus chart with customizable nullplatform port -- Configures Kubernetes namespace for Prometheus deployment -- Creates necessary Kubernetes resources for Prometheus +- Deploys prometheus-community/prometheus Helm chart with a mandatory pinned version to prevent version drift +- Creates a dedicated Kubernetes namespace automatically via helm_release create_namespace +- Renders a templated Prometheus values YAML file with configurable nullplatform service port +- Enforces atomic Helm releases with automatic cleanup on failure and pod recreation +- Configures Helm release with dependency_update and max_history tracking for safe upgrades ## Basic Usage ```hcl module "prometheus" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/prometheus?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/prometheus?ref=v8.0.0" + + prometheus_version = "your-prometheus-version" +} +``` + +### Usage with Latest Version (Blocked) + +```hcl +module "prometheus" { + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/prometheus?ref=v8.0.0" + + prometheus_version = "latest" +} +``` + +### Usage with Main Branch Reference (Blocked) + +```hcl +module "prometheus" { + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/prometheus?ref=v8.0.0" + + prometheus_version = "main" +} +``` + +### Usage with Master Branch Reference (Blocked) + +```hcl +module "prometheus" { + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/commons/prometheus?ref=v8.0.0" + + prometheus_version = "master" } ``` @@ -42,7 +76,7 @@ resource "example_resource" "this" { | Name | Version | |------|---------| -| [helm](#provider\_helm) | ~> 3.0 | +| [helm](#provider\_helm) | 3.2.0 | ## Resources @@ -56,19 +90,27 @@ resource "example_resource" "this" { |------|-------------|------|---------|:--------:| | [nullplatform\_port](#input\_nullplatform\_port) | Port number for nullplatform service communication | `number` | `2021` | no | | [prometheus\_namespace](#input\_prometheus\_namespace) | Kubernetes namespace where Prometheus will be deployed | `string` | `"prometheus"` | no | +| [prometheus\_version](#input\_prometheus\_version) | No default: every install pins this deliberately — see VERSIONS.md. Helm chart version for the prometheus-community/prometheus chart. The helm\_release carried no version at all, so every apply resolved to whatever the repository served latest; the default is the version that resolved to as of 2026-08-27, which keeps behaviour unchanged while removing the drift. | `string` | n/a | yes | diff --git a/infrastructure/gcp/artifact-registry/README.md b/infrastructure/gcp/artifact-registry/README.md index 8478052f..ed951060 100644 --- a/infrastructure/gcp/artifact-registry/README.md +++ b/infrastructure/gcp/artifact-registry/README.md @@ -2,26 +2,26 @@ ## Description -Creates a Google Artifact Registry repository with an associated service account configured for Workload Identity bindings to Kubernetes service accounts +Creates a Google Artifact Registry repository with a dedicated service account, optional Workload Identity bindings for GKE pods, and an optional static JSON key for external Docker clients ## Architecture -The module provisions a google_artifact_registry_repository resource in the specified GCP project and location. A google_service_account is created and granted roles/artifactregistry.writer permissions via google_project_iam_member to enable push/pull operations. For each entry in workload_identity_bindings, a google_service_account_iam_member resource grants roles/iam.workloadIdentityUser to the corresponding Kubernetes service account, establishing the Workload Identity federation link between GKE pods and the GCP service account. +The module provisions a google_artifact_registry_repository resource configured with project, location, repository ID, format, and labels. A google_service_account named artifact-registry-sa is created and granted roles/artifactregistry.writer on the project via google_project_iam_member. For each entry in workload_identity_bindings, a google_service_account_iam_member resource binds roles/iam.workloadIdentityUser to the corresponding Kubernetes ServiceAccount identity, enabling GKE Workload Identity. When generate_key is true, a google_service_account_key resource is created with optional keepers wired to key_rotation_token, and its base64-encoded private key is exposed as a sensitive output. ## Features -- Creates Google Artifact Registry repository with configurable format (DOCKER, NPM, PYTHON) -- Provisions a dedicated GCP service account with artifactregistry.writer role for image operations -- Configures Workload Identity bindings to allow Kubernetes service accounts to impersonate the GCP service account -- Outputs fully-qualified Docker-compatible repository URL for image push/pull operations -- Supports custom labels/tags on the Artifact Registry repository -- Enables multi-namespace Kubernetes service account bindings through dynamic for_each configuration +- Creates a Google Artifact Registry repository with configurable format (DOCKER, NPM, PYTHON, etc.) and labels +- Provisions a dedicated GCP service account with roles/artifactregistry.writer scoped to the project +- Binds multiple Kubernetes ServiceAccounts to the GCP service account via Workload Identity using google_service_account_iam_member +- Generates an optional static JSON service account key for external Docker clients unable to use Workload Identity +- Supports key rotation by wiring an arbitrary token to google_service_account_key keepers to force reissuance on change +- Outputs a fully-qualified Docker-compatible repository URL for immediate use in image push/pull configurations ## Basic Usage ```hcl module "artifact-registry" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/artifact-registry?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/artifact-registry?ref=v8.0.0" location = "your-location" project_id = "your-project-id" @@ -60,12 +60,15 @@ resource "example_resource" "this" { | [google_project_iam_member.artifact_sa_role](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource | | [google_service_account.artifact_sa](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | | [google_service_account_iam_member.workload_identity](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource | +| [google_service_account_key.artifact_sa_key](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_key) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [format](#input\_format) | The format (DOCKER, NPM, PYTHON, etc) | `string` | `"DOCKER"` | no | +| [generate\_key](#input\_generate\_key) | Generate a static JSON key for the Artifact Registry service account, exposed via the service\_account\_key\_base64 output. Only needed for callers outside the cluster (e.g. an external system authenticating as a Docker registry client) that can't use Workload Identity. Leave false when every consumer runs in-cluster. Note that the key material is stored in plaintext in Terraform/OpenTofu state, and the service account holds roles/artifactregistry.writer at PROJECT scope. | `bool` | `false` | no | +| [key\_rotation\_token](#input\_key\_rotation\_token) | Arbitrary value wired to the service account key's keepers. Changing it forces a new key to be issued, which is the supported way to rotate: GCP user-managed keys do not expire on their own. Leave null to never rotate. Do not derive this from timestamp() or uuid() — the key would be reissued on every apply | `string` | `null` | no | | [location](#input\_location) | The location for the repository | `string` | n/a | yes | | [project\_id](#input\_project\_id) | The GCP project ID | `string` | n/a | yes | | [repository\_id](#input\_repository\_id) | The repository ID (name) | `string` | n/a | yes | @@ -79,20 +82,21 @@ resource "example_resource" "this" { | [repository\_id](#output\_repository\_id) | The Artifact Registry repository ID | | [repository\_url](#output\_repository\_url) | The fully-qualified Docker-compatible URL of the Artifact Registry repository | | [service\_account\_email](#output\_service\_account\_email) | GCP Service Account email. Annotate the Kubernetes ServiceAccount bound via workload\_identity\_bindings with iam.gke.io/gcp-service-account= to impersonate this account from pods. | +| [service\_account\_key\_base64](#output\_service\_account\_key\_base64) | Base64-encoded JSON key for the Artifact Registry service account, for Docker clients that authenticate with username '\_json\_key\_base64' and this value as the password. Null unless generate\_key is true. | diff --git a/infrastructure/gcp/backend/README.md b/infrastructure/gcp/backend/README.md index 7711ec7d..3dc9ca3b 100644 --- a/infrastructure/gcp/backend/README.md +++ b/infrastructure/gcp/backend/README.md @@ -2,27 +2,27 @@ ## Description -Creates a GCS bucket for storing Terraform/OpenTofu remote state with configurable storage class, versioning, encryption, access control, and audit logging +Creates a GCS bucket for Terraform/OpenTofu remote state with access logging, versioning, optional KMS encryption, and IAM member bindings ## Architecture -The module creates a random_id resource to generate a unique 8-byte hex suffix, which is appended to the lowercased bucket_prefix to form the globally unique name of a google_storage_bucket resource. Optional CMEK encryption is wired via a dynamic encryption block that activates only when kms_key_name is non-null and non-empty, and optional access logging is wired via a dynamic logging block that activates only when log_bucket is non-null and non-empty. Zero or more google_storage_bucket_iam_member resources are created via for_each over the allowed_members list, each granting roles/storage.objectAdmin on the bucket. Outputs expose the bucket name, gs:// URL, self-link, and location for use by remote state backend configurations. +The module creates a primary google_storage_bucket (tf_state) with a random_id suffix for global uniqueness, and conditionally creates a second google_storage_bucket (logs) when no external log bucket is provided. A data source google_storage_project_service_account retrieves the GCS service agent, and a google_storage_bucket_iam_member (logs_writer) grants it objectCreator on the auto-created log bucket. Additional google_storage_bucket_iam_member resources (allowed_members) are created via for_each to grant objectAdmin to any caller-supplied IAM principals on the state bucket. ## Features -- Creates a google_storage_bucket with a globally unique name by appending a random 16-character hex suffix to a caller-supplied prefix -- Enables object versioning on the bucket so previous Terraform state revisions can be recovered -- Configures uniform bucket-level access and public access prevention to enforce IAM-only access controls -- Attaches optional Cloud KMS customer-managed encryption key via a dynamic encryption block on the bucket -- Enables optional GCS access logging to a separate audit log bucket via a dynamic logging block -- Grants roles/storage.objectAdmin to an arbitrary list of IAM members via google_storage_bucket_iam_member resources -- Supports configurable storage class across standard, nearline, coldline, archive, and legacy GCS storage tiers +- Creates a globally unique GCS bucket for Terraform/OpenTofu state with a random 16-character hex suffix appended to a caller-supplied prefix +- Enables object versioning by default so previous state revisions can be recovered +- Enforces public access prevention and uniform bucket-level access (IAM-only) by default +- Automatically creates a dedicated access-log bucket and grants the GCS service agent write access when no external log bucket is provided +- Supports optional customer-managed KMS encryption via an existing Cloud KMS key +- Grants additional IAM members roles/storage.objectAdmin on the state bucket via additive IAM bindings +- Applies caller-supplied labels to both the state bucket and the auto-created log bucket ## Basic Usage ```hcl module "backend" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/backend?ref=v6.22.1" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/backend?ref=v8.0.0" project_id = "your-project-id" } @@ -57,8 +57,10 @@ resource "example_resource" "this" { | Name | Type | |------|------| +| [google_storage_bucket.logs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket) | resource | | [google_storage_bucket.tf_state](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket) | resource | | [google_storage_bucket_iam_member.allowed_members](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_iam_member) | resource | +| [google_storage_bucket_iam_member.logs_writer](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_iam_member) | resource | | [random_id.bucket_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | ## Inputs @@ -70,7 +72,7 @@ resource "example_resource" "this" { | [force\_destroy](#input\_force\_destroy) | Allow destruction of the bucket even if it contains objects. Leave false to protect Terraform/OpenTofu state from accidental deletion | `bool` | `false` | no | | [kms\_key\_name](#input\_kms\_key\_name) | Full resource name of an existing Cloud KMS key used to encrypt the bucket's contents. Leave null or empty to use Google-managed encryption. When set, the project's GCS service agent must already hold roles/cloudkms.cryptoKeyEncrypterDecrypter on the key — this module does not grant it | `string` | `null` | no | | [location](#input\_location) | GCS location for the bucket (e.g. a multi-region like US, or a region like us-central1) | `string` | `"US"` | no | -| [log\_bucket](#input\_log\_bucket) | Name of an existing GCS bucket to receive this bucket's access logs. Leave null or empty to disable access logging. Recommended for a state bucket, so reads of state objects leave an audit trail | `string` | `null` | no | +| [log\_bucket](#input\_log\_bucket) | Name of an existing GCS bucket to receive this bucket's access logs. Leave null or empty and the module creates its own dedicated log bucket (and grants the GCS service agent write access to it) — access logging is always on, so reads of state objects leave an audit trail. | `string` | `null` | no | | [project\_id](#input\_project\_id) | The GCP project ID where the state bucket will be created | `string` | n/a | yes | | [public\_access\_prevention](#input\_public\_access\_prevention) | Public access prevention setting for the bucket (enforced or inherited) | `string` | `"enforced"` | no | | [storage\_class](#input\_storage\_class) | Storage class for the bucket | `string` | `"STANDARD"` | no | @@ -86,21 +88,22 @@ resource "example_resource" "this" { | [bucket\_self\_link](#output\_bucket\_self\_link) | Self-link of the GCS bucket | | [bucket\_url](#output\_bucket\_url) | gs:// URL of the GCS bucket | | [location](#output\_location) | Location of the GCS bucket | +| [log\_bucket\_name](#output\_log\_bucket\_name) | Name of the bucket receiving access logs — either var.log\_bucket, or the module's own auto-created log bucket when that's left unset | diff --git a/infrastructure/gcp/cloud-dns/README.md b/infrastructure/gcp/cloud-dns/README.md index e16c9eb8..9b6db792 100644 --- a/infrastructure/gcp/cloud-dns/README.md +++ b/infrastructure/gcp/cloud-dns/README.md @@ -21,7 +21,7 @@ The module creates a single google_dns_managed_zone resource in the specified GC ```hcl module "cloud-dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/cloud-dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/cloud-dns?ref=v8.0.0" domain_name = "your-domain-name" project_id = "your-project-id" diff --git a/infrastructure/gcp/cloud-nat/README.md b/infrastructure/gcp/cloud-nat/README.md index e63567b8..7d3aa158 100644 --- a/infrastructure/gcp/cloud-nat/README.md +++ b/infrastructure/gcp/cloud-nat/README.md @@ -19,7 +19,7 @@ This module creates a google_compute_router resource in a specified region and n ```hcl module "cloud-nat" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/cloud-nat?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/cloud-nat?ref=v8.0.0" nat_name = "your-nat-name" network_id = "your-network-id" diff --git a/infrastructure/gcp/gke/README.md b/infrastructure/gcp/gke/README.md index 0afe40df..0f7bd65a 100644 --- a/infrastructure/gcp/gke/README.md +++ b/infrastructure/gcp/gke/README.md @@ -2,25 +2,27 @@ ## Description -Deploys a private GKE cluster with a public endpoint and configures node pools and security defaults +Provisions a private GKE cluster on GCP in either standard (manually managed node pools) or Autopilot mode, deployed into an existing VPC with private nodes and a public API endpoint ## Architecture -The module uses the google-modules/kubernetes-engine/google//modules/private-cluster Terraform module to create a GKE cluster with a private endpoint and public access, and configures node pools and security defaults using variables such as node_pools, authorized_ip_ranges, and deletion_protection_enabled, the module also creates a service account with Artifact Registry access and sets up logging and monitoring +The module conditionally creates either a `terraform-google-modules/kubernetes-engine/google//modules/private-cluster` resource (standard mode) or a `terraform-google-modules/kubernetes-engine/google//modules/beta-autopilot-private-cluster` resource (Autopilot mode) using count-based toggling on `var.autopilot_enabled`. In standard mode, node pools are derived from `var.node_pools` via a local that strips null-valued optional attributes before passing them to the wrapped module, which creates the cluster with private nodes, a dedicated service account with Artifact Registry access, and cloud logging disabled. A `moved` block preserves state addresses for consumers upgrading from a module version that lacked the count meta-argument, preventing destroy-and-recreate plans. ## Features -- Creates GKE cluster with private endpoint and public access -- Configures node pools with machine type, min and max count, and disk size -- Sets up security defaults including deletion protection and authorized IP ranges -- Creates service account with Artifact Registry access -- Configures logging and monitoring for the GKE cluster +- Creates a private GKE cluster with private nodes and a public API endpoint using secondary IP ranges for pods and services +- Supports both standard clusters with manually managed node pools and fully managed Autopilot clusters via a single boolean toggle +- Configures per-pool autoscaling with both per-zone (min_count/max_count) and cluster-wide (total_min_count/total_max_count) bounds +- Creates a dedicated GCP service account with Artifact Registry read access for node image pulls +- Supports Spot and Preemptible node pool configurations with mutual exclusivity validation +- Applies node taints per pool and globally via node_pools_taints to control workload scheduling on cost-optimized nodes +- Restricts Kubernetes API server access to configurable authorized IP CIDR ranges ## Basic Usage ```hcl module "gke" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/gke?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/gke?ref=v8.0.0" cluster_name = "your-cluster-name" ip_range_pods = "your-ip-range-pods" @@ -48,25 +50,29 @@ resource "example_resource" "this" { |------|---------| | [terraform](#requirement\_terraform) | >= 1.3 | | [google](#requirement\_google) | ~> 5.0 | +| [google-beta](#requirement\_google-beta) | ~> 5.0 | ## Modules | Name | Source | Version | |------|--------|---------| | [gke](#module\_gke) | terraform-google-modules/kubernetes-engine/google//modules/private-cluster | ~> 33.0 | +| [gke\_autopilot](#module\_gke\_autopilot) | terraform-google-modules/kubernetes-engine/google//modules/beta-autopilot-private-cluster | ~> 33.0 | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [authorized\_ip\_ranges](#input\_authorized\_ip\_ranges) | List of authorized IP ranges allowed to access the Kubernetes API server |
list(object({
cidr_block = string
display_name = string
}))
| `[]` | no | +| [autopilot\_enabled](#input\_autopilot\_enabled) | Create a GKE Autopilot cluster instead of a standard cluster with manually managed node pools. When true, node\_pools is ignored — Autopilot provisions and scales nodes automatically per workload. | `bool` | `false` | no | | [cluster\_name](#input\_cluster\_name) | The name of the GKE cluster | `string` | n/a | yes | | [deletion\_protection\_enabled](#input\_deletion\_protection\_enabled) | Whether to enable deletion protection for the GKE cluster | `bool` | `false` | no | | [ip\_range\_pods](#input\_ip\_range\_pods) | The name of the secondary IP range for pods | `string` | n/a | yes | | [ip\_range\_services](#input\_ip\_range\_services) | The name of the secondary IP range for services | `string` | n/a | yes | | [location](#input\_location) | The GCP region where the GKE cluster will be deployed (e.g., us-central1, europe-west1) | `string` | n/a | yes | | [master\_ipv4\_cidr\_block](#input\_master\_ipv4\_cidr\_block) | The IP range in CIDR notation for the hosted master network (e.g., 172.16.0.0/28) | `string` | `"172.16.0.0/28"` | no | -| [node\_pools](#input\_node\_pools) | List of node pools to create in the GKE cluster |
list(object({
name = string
machine_type = optional(string, "e2-medium")
min_count = optional(number, 1)
max_count = optional(number, 3)
disk_size_gb = optional(number, 100)
}))
|
[
{
"name": "default"
}
]
| no | +| [node\_pools](#input\_node\_pools) | List of node pools to create in the GKE cluster (ignored when autopilot\_enabled is true). min\_count, max\_count and node\_count are PER ZONE and the cluster is regional, so they are multiplied by the number of zones in the region; use total\_min\_count/total\_max\_count for cluster-wide bounds |
list(object({
name = string
machine_type = optional(string, "e2-medium")
disk_size_gb = optional(number, 100)
# When autoscaling is true (the default), the pool scales between
# min_count and max_count. When false, it holds a fixed node_count.
autoscaling = optional(bool, true)
# PER ZONE. This module creates regional clusters (location is passed as
# region), so the effective cluster-wide count is these values multiplied by
# the number of zones in the region — three, in most regions. Use
# total_min_count/total_max_count instead to express cluster-wide bounds.
min_count = optional(number, 1)
max_count = optional(number, 3)
# PER ZONE, same multiplication as above. Only used when autoscaling is false.
node_count = optional(number, 1)
# Cluster-wide autoscaling bounds. When set, they replace the per-zone
# min_count/max_count. Must be set together.
total_min_count = optional(number)
total_max_count = optional(number)
# spot and preemptible are mutually exclusive lower-cost VM options;
# leave both false for regular on-demand nodes. Note that GKE does NOT taint
# spot nodes in standard clusters — it only labels them — so any pod without
# a nodeSelector can land on preemptible capacity. Use node_pools_taints to
# keep workloads off them.
spot = optional(bool, false)
preemptible = optional(bool, false)
}))
|
[
{
"name": "default"
}
]
| no | +| [node\_pools\_taints](#input\_node\_pools\_taints) | Node taints by node-pool name, plus an optional 'all' key applied to every pool. Needed to keep ordinary workloads off spot/preemptible pools: GKE adds only labels to Spot nodes in standard clusters, and applies the cloud.google.com/gke-spot NoSchedule taint solely through node auto-provisioning, which is not this path. Pools absent from the map get no taints |
map(list(object({
key = string
value = string
effect = string
})))
| `{}` | no | | [project\_id](#input\_project\_id) | The GCP project ID | `string` | n/a | yes | | [tags](#input\_tags) | A mapping of labels to assign to the GKE cluster and related resources | `map(string)` | `{}` | no | | [vpc\_name](#input\_vpc\_name) | The name of the virtual private network | `string` | n/a | yes | @@ -84,14 +90,16 @@ resource "example_resource" "this" { diff --git a/infrastructure/gcp/iam/README.md b/infrastructure/gcp/iam/README.md index c6e46e95..d0626ba7 100644 --- a/infrastructure/gcp/iam/README.md +++ b/infrastructure/gcp/iam/README.md @@ -19,7 +19,7 @@ The module creates google_service_account resources for each service account spe ```hcl module "iam" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/iam?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/iam?ref=v8.0.0" project_id = "your-project-id" } diff --git a/infrastructure/gcp/security/README.md b/infrastructure/gcp/security/README.md index 66abb5ae..15d5aa97 100644 --- a/infrastructure/gcp/security/README.md +++ b/infrastructure/gcp/security/README.md @@ -2,24 +2,27 @@ ## Description -Configures GCP firewall rules for Istio gateways in a GKE cluster +Creates GCP firewall rules for Istio public and private gateways on GKE, restricting health check port 15021 to VPC CIDR and GCP health checker ranges while allowing HTTPS on port 443 ## Architecture -This module uses Terraform to create GCP firewall rules for public and private Istio gateways in a GKE cluster. It utilizes the google_compute_firewall resource to define ingress rules for HTTPS and health check traffic. The module also derives the network and CIDR block from the GKE cluster information using data sources like google_container_cluster and google_compute_subnetwork. The firewall rules are then created based on the derived network and CIDR block, with specific rules for public and private gateways. The module also outputs the names of the created firewall rules for public and private gateways. +The module uses data.google_container_cluster to derive the VPC network name and data.google_compute_subnetwork to derive the subnet CIDR, both skipped when override variables are supplied. These derived or overridden values flow into google_compute_firewall resources for public and private gateways, each controlled by boolean flags. For the public gateway, three google_compute_firewall rules are created: one allowing 443 from 0.0.0.0/0, one allowing 15021 from VPC CIDR plus GCP health check ranges, and a lower-priority deny rule blocking 15021 from the internet. For the private gateway, two google_compute_firewall rules restrict both 443 and 15021 to VPC CIDR plus GCP health check ranges, with all rules targeting nodes via cluster-name-prefixed network tags. ## Features -- Creates GCP firewall rules for public and private Istio gateways -- Configures ingress rules for HTTPS and health check traffic -- Derives network and CIDR block from GKE cluster information -- Outputs firewall rule names for public and private gateways +- Creates google_compute_firewall rules for Istio public gateway allowing HTTPS (443) from the internet +- Creates google_compute_firewall deny rule blocking health check port 15021 from the internet at lower priority +- Creates google_compute_firewall rules for Istio private gateway restricting HTTPS to VPC CIDR only +- Allows GCP load balancer health check ranges (35.191.0.0/16, 130.211.0.0/22) access to port 15021 for both gateways +- Derives VPC network name and subnet CIDR automatically from data.google_container_cluster and data.google_compute_subnetwork when not supplied +- Skips data source lookups entirely when both gcp_network_name and network_cidr overrides are provided, avoiding the need for container.clusters.get or compute.subnetworks.get permissions +- Targets firewall rules to specific GKE nodes using cluster-name-prefixed network tags for public and private gateways ## Basic Usage ```hcl module "security" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/security?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/security?ref=v8.0.0" cluster_name = "your-cluster-name" gcp_project_id = "your-gcp-project-id" @@ -47,7 +50,7 @@ resource "example_resource" "this" { | Name | Version | |------|---------| -| [google](#provider\_google) | ~> 5.0 | +| [google](#provider\_google) | 5.45.2 | ## Resources @@ -66,10 +69,10 @@ resource "example_resource" "this" { | [cluster\_name](#input\_cluster\_name) | The GKE cluster name, used for naming firewall rules and deriving network. | `string` | n/a | yes | | [gateway\_internal\_enabled](#input\_gateway\_internal\_enabled) | Whether the internal (private) gateway is enabled. | `bool` | `false` | no | | [gateways\_enabled](#input\_gateways\_enabled) | Whether public gateways are enabled. | `bool` | `true` | no | -| [gcp\_network\_name](#input\_gcp\_network\_name) | Override: The VPC network name. If empty, derived from cluster. | `string` | `""` | no | +| [gcp\_network\_name](#input\_gcp\_network\_name) | Override: The VPC network name. If empty, derived from the cluster. Supplying this together with network\_cidr skips the cluster and subnetwork lookups entirely, so the caller does not need container.clusters.get or compute.subnetworks.get. Accepts a bare name or a full projects/P/global/networks/N path — google\_compute\_firewall normalizes either | `string` | `""` | no | | [gcp\_project\_id](#input\_gcp\_project\_id) | The GCP project ID. | `string` | n/a | yes | | [gcp\_region](#input\_gcp\_region) | The GCP region where the GKE cluster is located. | `string` | n/a | yes | -| [network\_cidr](#input\_network\_cidr) | Override: The network CIDR block. If empty, derived from subnet. | `string` | `""` | no | +| [network\_cidr](#input\_network\_cidr) | Override: The network CIDR block. If empty, derived from the cluster's subnetwork. Supplying it skips the subnetwork lookup. Needed when the derived path cannot be resolved by the caller's credentials, e.g. a Shared VPC subnet in a host project the module cannot read | `string` | `""` | no | ## Outputs @@ -82,13 +85,16 @@ resource "example_resource" "this" { diff --git a/infrastructure/gcp/vpc/README.md b/infrastructure/gcp/vpc/README.md index d8d6e693..f7984f96 100644 --- a/infrastructure/gcp/vpc/README.md +++ b/infrastructure/gcp/vpc/README.md @@ -20,7 +20,7 @@ The module invokes the terraform-google-modules/network/google module to create ```hcl module "vpc" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/vpc?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/gcp/vpc?ref=v8.0.0" network_name = "your-network-name" project_id = "your-project-id" diff --git a/infrastructure/oci/backend/README.md b/infrastructure/oci/backend/README.md index d1f54f7b..47346c46 100644 --- a/infrastructure/oci/backend/README.md +++ b/infrastructure/oci/backend/README.md @@ -18,7 +18,7 @@ The module creates an oci_objectstorage_bucket resource, which is configured wit ```hcl module "backend" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/backend?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/backend?ref=v8.0.0" compartment_id = "your-compartment-id" namespace = "your-namespace" diff --git a/infrastructure/oci/dns/README.md b/infrastructure/oci/dns/README.md index f111be69..e94e6cf2 100644 --- a/infrastructure/oci/dns/README.md +++ b/infrastructure/oci/dns/README.md @@ -18,7 +18,7 @@ This module creates oci_dns_zone resources for each DNS zone defined in the dns_ ```hcl module "dns" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/dns?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/dns?ref=v8.0.0" compartment_id = "your-compartment-id" } diff --git a/infrastructure/oci/dynamic_groups/README.md b/infrastructure/oci/dynamic_groups/README.md index 826f78f7..7e44980d 100644 --- a/infrastructure/oci/dynamic_groups/README.md +++ b/infrastructure/oci/dynamic_groups/README.md @@ -19,7 +19,7 @@ This module creates an OCI dynamic group and an OCI identity policy, connecting ```hcl module "dynamic_groups" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/dynamic_groups?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/dynamic_groups?ref=v8.0.0" cluster_id = "your-cluster-id" compartment_id = "your-compartment-id" diff --git a/infrastructure/oci/oke/README.md b/infrastructure/oci/oke/README.md index b4afda83..fc64f375 100644 --- a/infrastructure/oci/oke/README.md +++ b/infrastructure/oci/oke/README.md @@ -21,7 +21,7 @@ The module instantiates the oracle-terraform-modules/oke/oci module to create an ```hcl module "oke" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/oke?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/oke?ref=v8.0.0" api_endpoint_subnet_id = "your-api-endpoint-subnet-id" cluster_name = "your-cluster-name" diff --git a/infrastructure/oci/vcn/README.md b/infrastructure/oci/vcn/README.md index ee7759b5..a706e841 100644 --- a/infrastructure/oci/vcn/README.md +++ b/infrastructure/oci/vcn/README.md @@ -19,7 +19,7 @@ The module instantiates oci_core_subnet resources for public and private subnets ```hcl module "vcn" { - source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/vcn?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/oci/vcn?ref=v8.0.0" } ``` diff --git a/nullplatform/account/README.md b/nullplatform/account/README.md index 2565f527..03d11d88 100644 --- a/nullplatform/account/README.md +++ b/nullplatform/account/README.md @@ -19,7 +19,7 @@ The module iterates over the `nullplatform_accounts` input map using `for_each` ```hcl module "account" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/account?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/account?ref=v8.0.0" nullplatform_accounts = "your-nullplatform-accounts" } diff --git a/nullplatform/agent/README.md b/nullplatform/agent/README.md index 97db9ba6..3879c008 100644 --- a/nullplatform/agent/README.md +++ b/nullplatform/agent/README.md @@ -2,34 +2,34 @@ ## Description -Deploys the Nullplatform agent to a Kubernetes cluster via a Helm release with multi-cloud provider support +Deploys the nullplatform agent to a Kubernetes cluster via a Helm chart, configuring cloud-provider-specific identity, worker orchestration, and traffic manager settings ## Architecture -The module renders a Helm values file using a templatefile() call that merges default configuration, cloud-specific environment variables, and extra envs into a single locals map. A helm_release resource named 'agent' deploys the 'nullplatform-agent' chart from the official Nullplatform Helm repository into the specified Kubernetes namespace, consuming the rendered values. A terraform_data resource tracks the api_key as a replace trigger, forcing pod recreation when the API key changes. Cross-provider variable validation is enforced via terraform_data preconditions that gate cloud-specific required inputs like aws_iam_role_arn and azure_* credentials before the Helm release proceeds. +The module renders a YAML values file via templatefile() from locally computed locals, then provisions a single helm_release resource named 'agent' targeting the nullplatform-agent chart from the official Helm repository. A terraform_data resource tracks the api_key to force helm_release replacement when credentials rotate, while a second terraform_data resource enforces cross-variable preconditions (e.g. aws_iam_role_arn for AWS, azure_* vars for Azure) before the release is applied. Cloud-provider-specific environment variables, worker patches, and ServiceAccount bindings are merged into the chart values, with extra_envs taking final precedence over all computed defaults. ## Features -- Deploys nullplatform-agent Helm chart with atomic install and automatic cleanup on failure -- Configures multi-cloud provider support for AWS, GCP, Azure, and OCI with provider-specific environment variable injection -- Creates Kubernetes namespace automatically if it does not already exist -- Injects NRN-parsed organization, account, and namespace tags into the agent configuration -- Merges scope repository, extra Git repositories, and deduplicates the final agent repo list -- Forces pod recreation via terraform_data trigger when the API key is rotated -- Supports custom init scripts, image pull secrets, and additional environment variables for agent customization +- Deploys nullplatform-agent helm_release with atomic rollback, cleanup-on-fail, and 10-release history cap +- Renders cloud-provider-specific Helm values for AWS (IAM role ARN injection), Azure (client credentials and resource group), GCP, and OCI +- Configures worker orchestrator patches to set ServiceAccount, memory limits, and environment variables per worker-orchestrated package +- Enforces pinned versioning for both the Helm chart and traffic manager image tag, rejecting empty or moving references like 'latest' +- Injects TRAFFIC_CONTAINER_IMAGE into worker env by combining agent_traffic_manager_repository and agent_traffic_manager_tag locals +- Supports namespace auto-creation via create_namespace and merges user-supplied extra_envs over all computed defaults +- Triggers full helm_release replacement via terraform_data when the api_key value changes ## Basic Usage ```hcl module "agent" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v7.1.0" - - api_key = "your-api-key" - cloud_provider = "your-cloud-provider" - cluster_name = "your-cluster-name" - image_tag = "your-image-tag" - nrn = "your-nrn" - tags_selectors = "your-tags-selectors" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + cloud_provider = "your-cloud-provider" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + tags_selectors = "your-tags-selectors" } ``` @@ -37,15 +37,15 @@ module "agent" { ```hcl module "agent" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v7.1.0" - - api_key = "your-api-key" - aws_iam_role_arn = "your-aws-iam-role-arn" # Required when cloud_provider = "aws" - cloud_provider = "aws" - cluster_name = "your-cluster-name" - image_tag = "your-image-tag" - nrn = "your-nrn" - tags_selectors = "your-tags-selectors" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + aws_iam_role_arn = "your-aws-iam-role-arn" # Required when cloud_provider = "aws" + cloud_provider = "aws" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + tags_selectors = "your-tags-selectors" } ``` @@ -53,14 +53,14 @@ module "agent" { ```hcl module "agent" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v7.1.0" - - api_key = "your-api-key" - cloud_provider = "gcp" - cluster_name = "your-cluster-name" - image_tag = "your-image-tag" - nrn = "your-nrn" - tags_selectors = "your-tags-selectors" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + cloud_provider = "gcp" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + tags_selectors = "your-tags-selectors" } ``` @@ -68,22 +68,20 @@ module "agent" { ```hcl module "agent" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v7.1.0" - - api_key = "your-api-key" - azure_client_id = "your-azure-client-id" # Required when cloud_provider = "azure" - azure_client_secret = "your-azure-client-secret" # Required when cloud_provider = "azure" - azure_resource_group = "your-azure-resource-group" # Required when cloud_provider = "azure" - azure_subscription_id = "your-azure-subscription-id" # Required when cloud_provider = "azure" - azure_tenant_id = "your-azure-tenant-id" # Required when cloud_provider = "azure" - cloud_provider = "azure" - cluster_name = "your-cluster-name" - image_tag = "your-image-tag" - nrn = "your-nrn" - private_gateway_name = "your-private-gateway-name" # Required when cloud_provider = "azure" - private_hosted_zone_rg = "your-private-hosted-zone-rg" # Required when cloud_provider = "azure" - public_gateway_name = "your-public-gateway-name" # Required when cloud_provider = "azure" - tags_selectors = "your-tags-selectors" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + azure_client_id = "your-azure-client-id" # Required when cloud_provider = "azure" + azure_client_secret = "your-azure-client-secret" # Required when cloud_provider = "azure" + azure_resource_group = "your-azure-resource-group" # Required when cloud_provider = "azure" + azure_subscription_id = "your-azure-subscription-id" # Required when cloud_provider = "azure" + azure_tenant_id = "your-azure-tenant-id" # Required when cloud_provider = "azure" + cloud_provider = "azure" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + private_hosted_zone_rg = "your-private-hosted-zone-rg" # Required when cloud_provider = "azure" + tags_selectors = "your-tags-selectors" } ``` @@ -91,14 +89,44 @@ module "agent" { ```hcl module "agent" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v7.1.0" - - api_key = "your-api-key" - cloud_provider = "oci" - cluster_name = "your-cluster-name" - image_tag = "your-image-tag" - nrn = "your-nrn" - tags_selectors = "your-tags-selectors" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + cloud_provider = "oci" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + tags_selectors = "your-tags-selectors" +} +``` + +### Usage with Pinned Helm Chart Version + +```hcl +module "agent" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "your-agent-traffic-manager-tag" + api_key = "your-api-key" + cloud_provider = "your-cloud-provider" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "fixed semver (e.g. 2.37.0)" + tags_selectors = "your-tags-selectors" +} +``` + +### Usage with Pinned Traffic Manager Tag + +```hcl +module "agent" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=v8.0.0" + + agent_traffic_manager_tag = "fixed semver (e.g. 1.8.0)" + api_key = "your-api-key" + cloud_provider = "your-cloud-provider" + image_tag = "your-image-tag" + nullplatform_agent_helm_version = "your-nullplatform-agent-helm-version" + tags_selectors = "your-tags-selectors" } ``` @@ -138,8 +166,9 @@ resource "example_resource" "this" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [agent\_repos\_extra](#input\_agent\_repos\_extra) | List of additional Git repositories used for extended agent configuration | `list(string)` | `[]` | no | -| [agent\_repos\_scope](#input\_agent\_repos\_scope) | Git repository URL containing agent scope configurations (format: repo#branch) | `string` | `"https://github.com/nullplatform/scopes.git#main"` | no | +| [agent\_repo](#input\_agent\_repo) | Git repositories (each with a ref) the agent clones for its legacy
command-executor exec flow. Joined into a comma-separated AGENT\_REPO
value, no spaces. Empty when every scope uses worker\_orchestrator instead.

Example:
agent\_repo = [
"https://github.com/nullplatform/scopes.git#v1.15.1",
"https://github.com/nullplatform/services-s-3.git#v0.3.0",
] | `list(string)` | `[]` | no | +| [agent\_traffic\_manager\_repository](#input\_agent\_traffic\_manager\_repository) | Container image repository for the traffic manager. Defaults to the official nullplatform image; override to pull from a mirror. Matches the pattern nullplatform/base uses for its own images. | `string` | `"public.ecr.aws/nullplatform/k8s-traffic-manager"` | no | +| [agent\_traffic\_manager\_tag](#input\_agent\_traffic\_manager\_tag) | No default: every install pins this deliberately — see VERSIONS.md. Image tag for the traffic manager, published to the agent as TRAFFIC\_CONTAINER\_IMAGE. Pinning this used to mean passing the whole image string through extra\_envs; the registry lives here so only the tag is exposed. extra\_envs still takes precedence for anyone who needs a digest or a mirrored path. | `string` | n/a | yes | | [api\_key](#input\_api\_key) | API key for authenticating with the nullplatform API | `string` | n/a | yes | | [aws\_iam\_role\_arn](#input\_aws\_iam\_role\_arn) | ARN of the AWS IAM role assigned to the agent | `string` | `""` | no | | [azure\_client\_id](#input\_azure\_client\_id) | Azure client ID for authentication | `string` | `null` | no | @@ -147,9 +176,9 @@ resource "example_resource" "this" { | [azure\_resource\_group](#input\_azure\_resource\_group) | Azure resource group name | `string` | `null` | no | | [azure\_subscription\_id](#input\_azure\_subscription\_id) | Azure subscription ID | `string` | `null` | no | | [azure\_tenant\_id](#input\_azure\_tenant\_id) | Azure tenant ID | `string` | `null` | no | -| [blue\_green\_ingress\_path](#input\_blue\_green\_ingress\_path) | Specifies the ingress path used for blue-green deployments to route traffic to the new version. | `string` | `""` | no | -| [cloud\_provider](#input\_cloud\_provider) | Cloud provider to use (aws, gcp, or azure) | `string` | n/a | yes | -| [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster where the nullplatform agent will be deployed | `string` | n/a | yes | +| [blue\_green\_ingress\_path](#input\_blue\_green\_ingress\_path) | Specifies the ingress path used for blue-green deployments to route traffic to the new version. Required when extra\_envs.INGRESS\_TYPE is 'istio' — the k8s scope's default template is AWS ALB Ingress and won't route traffic correctly through Istio, so it must be pointed at an Istio HTTPRoute template instead. | `string` | `""` | no | +| [cloud\_provider](#input\_cloud\_provider) | Cloud provider to use ('aws', 'gcp', 'azure', or 'oci') | `string` | n/a | yes | +| [create\_namespace](#input\_create\_namespace) | Create the namespace if it does not exist. Leave true unless another module already owns it: nullplatform/base declares the same namespace with Helm ownership metadata, so with no ordering edge between the two whichever applies second fails. | `bool` | `true` | no | | [dns\_type](#input\_dns\_type) | Type of DNS Provider, ej: azure, route53, or external\_dns | `string` | `""` | no | | [domain](#input\_domain) | Base domain name used across resources | `string` | `""` | no | | [extra\_envs](#input\_extra\_envs) | Additional environment variables to pass to the agent | `map(string)` | `{}` | no | @@ -157,35 +186,35 @@ resource "example_resource" "this" { | [image\_repository](#input\_image\_repository) | Container image repository for the agent. Defaults to the official nullplatform image. | `string` | `""` | no | | [image\_tag](#input\_image\_tag) | Image tag for the agent container image | `string` | n/a | yes | | [init\_scripts](#input\_init\_scripts) | List of initialization scripts to execute during agent startup | `list(string)` | `[]` | no | -| [initial\_ingress\_path](#input\_initial\_ingress\_path) | Defines the initial ingress path used when deploying the application for the first time. | `string` | `""` | no | +| [initial\_ingress\_path](#input\_initial\_ingress\_path) | Defines the initial ingress path used when deploying the application for the first time. Required when extra\_envs.INGRESS\_TYPE is 'istio' — the k8s scope's default template is AWS ALB Ingress and won't route traffic correctly through Istio, so it must be pointed at an Istio HTTPRoute template instead. | `string` | `""` | no | | [namespace](#input\_namespace) | Kubernetes namespace where the nullplatform agent will run | `string` | `"nullplatform-tools"` | no | -| [nrn](#input\_nrn) | Nullplatform Resource Name - unique identifier for nullplatform resources | `string` | n/a | yes | -| [nullplatform\_agent\_helm\_version](#input\_nullplatform\_agent\_helm\_version) | Version of the nullplatform agent Helm chart to deploy | `string` | `"2.37.0"` | no | -| [private\_domain](#input\_private\_domain) | Private domain name used for internal agent routing | `string` | `""` | no | -| [private\_gateway\_name](#input\_private\_gateway\_name) | Private gateway name for Azure networking | `string` | `null` | no | +| [nullplatform\_agent\_helm\_version](#input\_nullplatform\_agent\_helm\_version) | No default: every install pins this deliberately — see VERSIONS.md. Version of the nullplatform agent Helm chart to deploy | `string` | n/a | yes | +| [private\_gateway\_name](#input\_private\_gateway\_name) | Name of the private/internal gateway used for routing | `string` | `"gateway-private"` | no | | [private\_hosted\_zone\_rg](#input\_private\_hosted\_zone\_rg) | Resource group for private hosted zone | `string` | `null` | no | -| [public\_gateway\_name](#input\_public\_gateway\_name) | Public gateway name for Azure networking | `string` | `null` | no | +| [public\_gateway\_name](#input\_public\_gateway\_name) | Name of the public gateway used for routing | `string` | `"gateway-public"` | no | | [release\_name](#input\_release\_name) | Override for the Helm release name. Defaults to nullplatform-agent | `string` | `"nullplatform-agent"` | no | -| [service\_account\_name](#input\_service\_account\_name) | Override for the Kubernetes ServiceAccount name created by the Helm chart | `string` | `""` | no | -| [service\_template](#input\_service\_template) | Specifies the name or reference of the scope service template to be used for deployment. | `string` | `""` | no | +| [service\_account\_name](#input\_service\_account\_name) | Override for the Kubernetes ServiceAccount name created by the Helm chart | `string` | `"nullplatform-agent"` | no | +| [service\_template](#input\_service\_template) | Specifies the name or reference of the scope service template to be used for deployment. Required when extra\_envs.INGRESS\_TYPE is 'istio' — the k8s scope's default template is AWS ALB Ingress and won't route traffic correctly through Istio, so it must be pointed at an Istio-compatible template instead. | `string` | `""` | no | | [tags\_selectors](#input\_tags\_selectors) | Map of tags used to select and filter channels and agents | `map(string)` | n/a | yes | -| [use\_account\_slug](#input\_use\_account\_slug) | Flag to determine whether to use account slug in resource naming | `string` | `""` | no | -| [worker](#input\_worker) | Worker-orchestration config, merged into the agent chart's `worker` block:
backend, security, allowedRegistries (deny-by-default registry guardrail),
patches (standard k8s patching of workers — the preferred way to shape them),
idleTTL (reap idle workers), and the legacy defaults/rules/pins. See the
nullplatform-agent chart values (>= 2.37.0) for the full shape. null = chart
defaults.

Example:
worker = {
allowedRegistries = ["public.ecr.aws/your-org/*"]
patches = [{ target = { package = "my-pkg" }, merge = { spec = { serviceAccountName = "np-agent-sa" } } }]
idleTTL = "30m"
} | `any` | `null` | no | +| [use\_account\_slug](#input\_use\_account\_slug) | Flag to determine whether to use the account slug in resource naming | `string` | `""` | no | +| [worker](#input\_worker) | Extra worker-orchestration config, merged on top of the module's own computed
worker block: backend ("kubernetes" by default), allowedRegistries
(["public.ecr.aws/nullplatform/*"] by default, so the platform's own scope
images keep working), and a patch for the worker container (2Gi memory
limit, the deploy/DNS env vars below, and a serviceAccountName that always
mirrors service\_account\_name). allowedRegistries and patches set here are
concatenated with (not replacing) the module defaults — add your own
registries or an extra patch rather than having to repeat the defaults;
set backend here to override it outright. Anything else — security, idleTTL
(reap idle workers), the legacy defaults/rules/pins — passes through as-is.
See the nullplatform-agent chart values (>= 2.37.0) for the full shape.
null = nothing extra.

Example:
worker = {
allowedRegistries = ["123456789012.dkr.ecr.us-east-1.amazonaws.com/your-org/*"]
patches = [{ target = { package = "my-pkg" }, merge = { spec = { serviceAccountName = "np-agent-sa" } } }]
idleTTL = "30m"
} | `any` | `null` | no | +| [worker\_memory\_limit](#input\_worker\_memory\_limit) | Memory limit for a worker-orchestrated package's pod (packages in var.worker\_orchestrated\_packages). The chart's own default is small enough to OOM mid-tofu-apply for packages that run real IaC tooling. | `string` | `"2Gi"` | no | +| [worker\_orchestrated\_packages](#input\_worker\_orchestrated\_packages) | Package slugs whose worker-orchestrator (package-exec) pods should run
under var.service\_account\_name (the same IRSA identity as the agent
itself) and var.worker\_memory\_limit, via a per-package worker-container
patch. Add a package's slug here whenever its worker needs to assume an
AWS role, or needs more memory than the chart's own default (e.g. to run
tofu/terraform); a worker for a package not listed here falls back to the
namespace's default ServiceAccount and the chart's own memory default.

This is separate from the "containers" scope's own k8s-deployment env
vars (DNS\_TYPE, DOMAIN, etc.), which remain specific to that package
regardless of what's listed here. | `list(string)` |
[
"containers"
]
| no | diff --git a/nullplatform/api_key/README.md b/nullplatform/api_key/README.md index 46e24fc6..b76c7f7d 100644 --- a/nullplatform/api_key/README.md +++ b/nullplatform/api_key/README.md @@ -2,26 +2,26 @@ ## Description -Creates a Nullplatform API key with pre-configured or custom role grants and tags based on a specified type +Creates and configures a nullplatform API key resource with pre-defined or custom role grants and tags based on the specified key type ## Architecture -The module creates a single nullplatform_api_key resource whose name, grants, and tags are derived from a locals-computed config map keyed by var.type. For predefined types (agent, scope_notification, service_notification), role slugs are expanded into grant blocks using the provided NRN, while the custom type allows fully user-defined grants via custom_grants or custom_role_slugs. Tags are merged from a static managedBy marker, NRN-parsed key-value pairs, and any user-supplied custom_tags, then injected as dynamic tag blocks on the resource. +The module defines a single nullplatform_api_key resource whose name, grants, and tags are driven by a locals.tf configuration map keyed on var.type. For predefined types (agent, base, scope_notification, service_notification), role slugs from the config map are expanded into dynamic grants blocks using the provided NRN, while custom type reads directly from var.custom_role_slugs or var.custom_grants. Tags are merged from NRN-parsed key-value pairs, a static managedBy label, and optional custom_tags, then injected via a dynamic tags block. Lifecycle preconditions enforce type-specific invariants such as requiring custom_name and at least one role or grant for the custom type, and specification_slug for notification types. ## Features -- Creates nullplatform_api_key with type-specific pre-configured role grants for agent, scope_notification, and service_notification workflows -- Supports fully custom API key configuration with user-defined name, role slugs, and per-grant NRN assignments -- Automatically parses NRN string into structured organization, account, and namespace tags applied to the API key -- Merges static managedBy IaC tag with NRN-derived tags and user-supplied custom tags into a unified tag set -- Enforces type-specific preconditions ensuring required variables like custom_name, specification_slug, and nrn are provided at plan time -- Generates scoped notification channel names using specification_slug for scope_notification and service_notification types +- Creates a nullplatform_api_key resource with pre-configured role grants for agent, base, scope_notification, and service_notification types +- Generates role grants dynamically from a type-keyed configuration map mapping role slugs to NRN-scoped grant blocks +- Parses the NRN string into structured tags automatically applied to the API key alongside a managedBy IaC label +- Supports fully custom API keys with caller-defined name, role slugs, or explicit per-grant NRN and role_slug pairs +- Enforces type-specific preconditions via Terraform lifecycle blocks to catch misconfiguration at plan time +- Outputs the sensitive API key value, resource ID, and key name for downstream consumption ## Basic Usage ```hcl module "api_key" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" type = "your-type" } @@ -31,18 +31,29 @@ module "api_key" { ```hcl module "api_key" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" nrn = "your-nrn" # Required when type = "agent" type = "agent" } ``` +### Usage with Base API Key + +```hcl +module "api_key" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" + + nrn = "your-nrn" # Required when type = "base" + type = "base" +} +``` + ### Usage with Scope Notification API Key ```hcl module "api_key" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" nrn = "your-nrn" # Required when type = "scope_notification" specification_slug = "your-specification-slug" # Required when type = "scope_notification" @@ -54,7 +65,7 @@ module "api_key" { ```hcl module "api_key" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" nrn = "your-nrn" # Required when type = "service_notification" specification_slug = "your-specification-slug" # Required when type = "service_notification" @@ -66,9 +77,8 @@ module "api_key" { ```hcl module "api_key" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/api_key?ref=v8.0.0" - custom_grants = "your-custom-grants" # Required when type = "custom" custom_name = "your-custom-name" # Required when type = "custom" custom_role_slugs = "your-custom-role-slugs" # Required when type = "custom" type = "custom" @@ -89,13 +99,13 @@ resource "example_resource" "this" { | Name | Version | |------|---------| -| [nullplatform](#requirement\_nullplatform) | ~> 0.0.86 | +| [nullplatform](#requirement\_nullplatform) | ~> 0.0.101 | ## Providers | Name | Version | |------|---------| -| [nullplatform](#provider\_nullplatform) | 0.0.95 | +| [nullplatform](#provider\_nullplatform) | 0.0.101 | ## Resources @@ -111,9 +121,10 @@ resource "example_resource" "this" { | [custom\_name](#input\_custom\_name) | Name for the API key (required when type is 'custom') | `string` | `null` | no | | [custom\_role\_slugs](#input\_custom\_role\_slugs) | List of role slugs to assign using the module-level NRN (used when type is 'custom' and custom\_grants is empty) | `list(string)` | `[]` | no | | [custom\_tags](#input\_custom\_tags) | Additional tags to apply to the API key (optional, only used when type is 'custom') |
list(object({
key = string
value = string
}))
| `[]` | no | -| [nrn](#input\_nrn) | Nullplatform Resource Name (e.g., organization=123:account=456:namespace=789). Required for predefined types (agent, scope\_notification, service\_notification). Optional for custom type when using custom\_grants. | `string` | `null` | no | +| [internal](#input\_internal) | Marks the API key as internal to nullplatform, keeping it out of the API key listing (`GET /api_key` and the UI) while it stays readable by ID — for the plumbing credentials this module creates (agents, notification channels) rather than keys a person manages. Create-only in the API, so changing it replaces the key and rotates its secret. Leave unset for the platform default (not internal). | `bool` | `null` | no | +| [nrn](#input\_nrn) | Nullplatform Resource Name (e.g., organization=123:account=456:namespace=789). Required for predefined types (agent, base, scope\_notification, service\_notification). Optional for custom type when using custom\_grants. | `string` | `null` | no | | [specification\_slug](#input\_specification\_slug) | Specification slug used for the usedBy tag (required for scope\_notification and service\_notification types) | `string` | `null` | no | -| [type](#input\_type) | Type of API key to create. Determines the pre-configured grants and tags. Use 'custom' to define your own roles and tags. | `string` | n/a | yes | +| [type](#input\_type) | Type of API key to create. Determines the pre-configured grants and tags. 'base' carries the agent roles minus secrets-reader, for the nullplatform base module. Use 'custom' to define your own roles and tags. | `string` | n/a | yes | ## Outputs @@ -127,25 +138,25 @@ resource "example_resource" "this" { diff --git a/nullplatform/asset/docker_server/README.md b/nullplatform/asset/docker_server/README.md index 1bdb223e..8a28d6b5 100644 --- a/nullplatform/asset/docker_server/README.md +++ b/nullplatform/asset/docker_server/README.md @@ -2,26 +2,25 @@ ## Description -Configures a Docker registry provider in nullplatform with server credentials and path settings +Configures a Docker server provider in nullplatform by creating a provider config resource with registry connection details ## Architecture -Creates a nullplatform_provider_config resource of type 'docker-server' with encoded JSON attributes containing Docker registry connection details. The module accepts credentials (login_server, username, password), path configuration, and optional dimensions for multi-tenant segmentation, then encodes these into a JSON attributes block that nullplatform uses to authenticate and route container image operations. The NRN (nullplatform resource name) links this provider configuration to specific nullplatform resources. +This module creates a single nullplatform_provider_config resource of type docker-server. The resource receives the NRN (nullplatform resource name) as its identifier and encodes the Docker registry connection attributes as a JSON payload. Input variables for login_server, path, username, and password are mapped directly into the attributes block using jsonencode, with use_namespace hardcoded to false. ## Features -- Creates Docker server provider configuration in nullplatform -- Configures Docker registry authentication with username and password credentials -- Sets registry path and login server endpoint for container image operations -- Supports multi-dimensional segmentation through optional dimensions map -- Defaults username to '_json_key_base64' for GCP service account authentication patterns -- Disables namespace usage in Docker registry configuration +- Creates a nullplatform_provider_config resource scoped to a specific NRN for Docker registry integration +- Encodes Docker server connection attributes as a structured JSON payload within the provider config +- Configures Docker registry access with login server URL, path, username, and password credentials +- Defaults username to '_json_key_base64' to support GCP Artifact Registry service account key authentication +- Disables namespace usage by hardcoding use_namespace to false in the registry setup ## Basic Usage ```hcl module "docker_server" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/docker_server?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/docker_server?ref=v8.0.0" login_server = "your-login-server" nrn = "your-nrn" @@ -62,7 +61,6 @@ resource "example_resource" "this" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [dimensions](#input\_dimensions) | Dimensions to segment the nullplatform provider config (e.g. by region, environment) | `map(string)` | `{}` | no | | [login\_server](#input\_login\_server) | Docker login server name | `string` | n/a | yes | | [nrn](#input\_nrn) | The nullplatform resource name (NRN) | `string` | n/a | yes | | [password](#input\_password) | Docker password | `string` | n/a | yes | @@ -73,15 +71,14 @@ resource "example_resource" "this" { diff --git a/nullplatform/asset/ecr/README.md b/nullplatform/asset/ecr/README.md index 50bede19..b987dd86 100644 --- a/nullplatform/asset/ecr/README.md +++ b/nullplatform/asset/ecr/README.md @@ -2,26 +2,26 @@ ## Description -Configures a Nullplatform ECR provider config resource that wires AWS ECR settings, IAM role ARN, and CI/CD credentials into the Nullplatform platform +Configures a Nullplatform ECR provider by registering AWS region, IAM role, CI/CD credentials, and repository settings as a nullplatform_provider_config resource ## Architecture -The module reads the current AWS region via the aws_region data source and combines it with input variables into a single nullplatform_provider_config resource of type 'ecr'. The provider config encodes two attribute blocks: a 'ci' block containing the AWS region and IAM access key credentials for the build workflow, and a 'setup' block containing the region, application IAM role ARN, repository naming rule, and optional repository policy. All values flow directly from input variables into the jsonencode'd attributes of the nullplatform_provider_config resource. +The module reads the current AWS region via the aws_region data source and combines it with input variables into a local setup map. A single nullplatform_provider_config resource of type 'ecr' is created, embedding CI credentials (access key ID and secret) alongside the setup block containing region, IAM role ARN, naming rule, and repository policy as a JSON-encoded attributes payload. The nrn variable scopes the provider config to a specific Nullplatform resource, and sensitive credentials are passed directly into the resource without additional wrapping. ## Features -- Creates a Nullplatform provider config resource of type 'ecr' scoped to a specific NRN -- Configures CI/CD build workflow credentials with AWS access key ID and secret for ECR image pushes -- Wires an application IAM role ARN for ECR image pull access into the provider setup block -- Supports a custom jq-based ECR repository naming convention defaulting to namespace/application slug format +- Creates a nullplatform_provider_config resource of type ECR to register the container registry provider +- Embeds CI/CD build workflow IAM credentials (access key ID and secret) for pipeline image push access +- Configures an IAM role ARN for application-level ECR image pull authorization +- Supports a customizable jq-based ECR repository naming convention via the naming_rule variable - Accepts an optional ECR repository policy JSON applied to all repositories created by Nullplatform -- Marks the build workflow secret access key as sensitive to prevent exposure in Terraform output +- Automatically resolves and injects the current AWS region from the aws_region data source ## Basic Usage ```hcl module "ecr" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/ecr?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/ecr?ref=v8.0.0" application_role_arn = "your-application-role-arn" build_workflow_access_key_id = "your-build-workflow-access-key-id" @@ -68,7 +68,6 @@ resource "example_resource" "this" { | [application\_role\_arn](#input\_application\_role\_arn) | ARN of the IAM role used by applications to pull ECR images | `string` | n/a | yes | | [build\_workflow\_access\_key\_id](#input\_build\_workflow\_access\_key\_id) | Access key ID for the CI/CD build workflow IAM user | `string` | n/a | yes | | [build\_workflow\_access\_key\_secret](#input\_build\_workflow\_access\_key\_secret) | Secret access key for the CI/CD build workflow IAM user | `string` | n/a | yes | -| [dimensions](#input\_dimensions) | Dimensions to segment the nullplatform provider config (e.g. by region, environment) | `map(string)` | `{}` | no | | [naming\_rule](#input\_naming\_rule) | jq expression for ECR repository naming convention. Defaults to the Nullplatform platform default. | `string` | `"\"\\(.namespace.slug)/\\(.application.slug)\""` | no | | [nrn](#input\_nrn) | The nullplatform resource name (NRN) | `string` | n/a | yes | | [repository\_policy](#input\_repository\_policy) | ECR repository policy JSON applied to every new repository Nullplatform creates (maps to 'setup.policy'). Leave empty to omit. | `string` | `""` | no | @@ -77,15 +76,15 @@ resource "example_resource" "this" { diff --git a/nullplatform/asset/s3/README.md b/nullplatform/asset/s3/README.md index 11492660..3ea4ca7b 100644 --- a/nullplatform/asset/s3/README.md +++ b/nullplatform/asset/s3/README.md @@ -2,24 +2,24 @@ ## Description -Configures a nullplatform S3 provider configuration resource linking an existing S3 bucket as the asset repository for a given NRN +Configures an S3 bucket as an asset repository in the nullplatform provider by registering its name under the s3-configuration provider config type ## Architecture -The module creates a single nullplatform_provider_config resource of type s3-configuration. The nrn input is used to scope the provider config to a specific nullplatform resource, while bucket_name is encoded as a JSON attribute defining the S3 bucket. The optional dimensions map allows segmenting the configuration by arbitrary key-value pairs such as region or environment. +The module creates a single nullplatform_provider_config resource of type s3-configuration tied to the given NRN scope. The bucket_name input is encoded as a JSON attributes payload and passed directly to the provider config resource. No additional resources or data sources are created; the module acts as a thin registration wrapper over the nullplatform provider API. ## Features -- Creates a nullplatform_provider_config resource of type s3-configuration targeting an existing S3 bucket -- Encodes bucket name as a JSON attribute payload within the provider configuration -- Supports dimensional segmentation of the provider config via an optional key-value dimensions map -- Scopes the S3 asset repository configuration to a specific nullplatform resource using the NRN identifier +- Registers an existing S3 bucket as the nullplatform asset repository configuration +- Encodes bucket metadata as a JSON attributes block for the nullplatform_provider_config resource +- Scopes the S3 provider configuration to a specific nullplatform resource via the NRN identifier +- Supports Lambda and bundle asset publishing workflows by linking the S3 bucket to the platform configuration ## Basic Usage ```hcl module "s3" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/s3?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/asset/s3?ref=v8.0.0" bucket_name = "your-bucket-name" nrn = "your-nrn" @@ -59,20 +59,19 @@ resource "example_resource" "this" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [bucket\_name](#input\_bucket\_name) | Name of the existing S3 bucket used as the asset repository, where Lambda/bundle assets are published. Maps to the platform's aws.s3\_assets\_bucket configuration. | `string` | n/a | yes | -| [dimensions](#input\_dimensions) | Dimensions to segment the nullplatform provider config (e.g. by region, environment) | `map(string)` | `{}` | no | | [nrn](#input\_nrn) | The nullplatform resource name (NRN) | `string` | n/a | yes | diff --git a/nullplatform/base/README.md b/nullplatform/base/README.md index f24e775e..7955d307 100644 --- a/nullplatform/base/README.md +++ b/nullplatform/base/README.md @@ -2,85 +2,103 @@ ## Description -Deploys the nullplatform base Helm chart onto a Kubernetes cluster across multiple cloud providers (EKS, GKE, AKS, OKE, ARO) with configurable gateways, ingress controllers, logging integrations, and observability backends +Deploys the nullplatform base Helm chart onto a Kubernetes cluster, wiring together namespaces, a control plane agent, logging controller, gateway resources, and observability integrations across multiple cloud providers ## Architecture -The module pre-creates two kubernetes_namespace_v1 resources ('nullplatform-tools' and 'nullplatform') to avoid Helm lookup race conditions, then deploys a single helm_release resource ('nullplatform-base') that depends on both namespaces. A templatefile() call in locals.tf renders a YAML values file by interpolating all input variables into a nullplatform_base_values.tmpl.yaml template, which is passed directly to the helm_release via its values argument. Outputs expose the rendered Helm values as a sensitive string plus cloud-specific security resource identifiers (AWS security group IDs, Azure NSG IDs, GCP firewall names) sourced directly from input variables. +The module creates two kubernetes_namespace_v1 resources ('nullplatform-tools' and 'nullplatform') as prerequisites to avoid Helm lookup race conditions, then deploys a single helm_release resource ('nullplatform-base') that depends on both namespaces. A templatefile local renders all input variables into a YAML values file consumed by the helm_release, covering ingress controllers, public/private gateways, control plane agent image coordinates, logging controller DaemonSet configuration, and per-provider observability sinks (CloudWatch, Datadog, Dynatrace, New Relic, Loki, GELF). Outputs expose the rendered values and cloud-provider-specific security resource identifiers (AWS security group IDs, Azure NSG IDs, GCP firewall names) for consumption by upstream modules. ## Features -- Creates two Kubernetes namespaces ('nullplatform-tools' and 'nullplatform') with Helm-compatible labels and annotations before chart installation -- Deploys the nullplatform-base Helm chart from the official nullplatform Helm repository with configurable chart version and 600-second job wait timeout -- Configures public and private Gateway API resources with per-cloud security bindings for AWS security groups, Azure NSGs, GCP firewall rules, and OCI security lists -- Supports multiple observability backends including Prometheus, Datadog, Dynatrace, New Relic, Loki, GELF, and CloudWatch with per-backend log and metrics toggles -- Renders a templated Helm values YAML via templatefile() that wires all provider-specific, gateway, ingress, logging, and authentication inputs into the chart -- Configures public and private ingress controllers with scope, domain, and enabled flags for multi-tenant traffic routing -- Supports image pull secrets for private container registries with configurable registry URL, username, and password +- Creates two Kubernetes namespaces ('nullplatform-tools' and 'nullplatform') before Helm release to eliminate chart lookup race conditions +- Deploys the nullplatform-base Helm chart with pinned version enforcement via validation that rejects empty strings and moving references like 'latest' +- Configures public and private Istio-compatible gateways with per-cloud security group, NSG, firewall, and OCI subnet annotations +- Enables pluggable observability backends including Prometheus, Loki, GELF, Datadog, Dynatrace, New Relic, and CloudWatch with independent log and metrics toggles +- Deploys a logging controller DaemonSet and control plane agent with image repository and pinned tag configuration +- Supports multi-cloud Kubernetes providers (EKS, GKE, AKS, OKE, ARO) with provider-specific gateway and load balancer annotations +- Manages image pull secrets and CloudWatch IRSA service account annotations for workload identity integration ## Basic Usage ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "your-k8s-provider" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "your-k8s-provider" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` -### Usage with Amazon EKS +### Usage with EKS (Amazon Elastic Kubernetes Service) ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "eks" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "eks" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` -### Usage with Google GKE +### Usage with GKE (Google Kubernetes Engine) ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "gke" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "gke" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` -### Usage with Azure AKS +### Usage with AKS (Azure Kubernetes Service) ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "aks" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "aks" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` -### Usage with Oracle OKE +### Usage with OKE (Oracle Container Engine for Kubernetes) ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "oke" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "oke" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` -### Usage with Azure Red Hat OpenShift (ARO) +### Usage with ARO (Azure Red Hat OpenShift) ```hcl module "base" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/base?ref=v8.0.0" - k8s_provider = "aro" - np_api_key = "your-np-api-key" + control_plane_agent_image_tag = "your-control-plane-agent-image-tag" + k8s_provider = "aro" + logging_controller_image_tag = "your-logging-controller-image-tag" + np_api_key = "your-np-api-key" + nullplatform_base_helm_version = "your-nullplatform-base-helm-version" } ``` @@ -127,6 +145,8 @@ resource "example_resource" "this" { | [cloudwatch\_logs\_enabled](#input\_cloudwatch\_logs\_enabled) | Enable log forwarding to CloudWatch. | `bool` | `false` | no | | [cloudwatch\_performance\_metrics\_enabled](#input\_cloudwatch\_performance\_metrics\_enabled) | Enable performance metrics in CloudWatch. | `bool` | `false` | no | | [cloudwatch\_service\_account\_annotations](#input\_cloudwatch\_service\_account\_annotations) | Annotations for the logs controller ServiceAccount (nullplatform-pod-metadata-reader-sa). Rendered only when cloudwatch\_enabled is true. Set eks.amazonaws.com/role-arn here to use IRSA instead of the node instance role. | `map(string)` | `{}` | no | +| [control\_plane\_agent\_image\_repository](#input\_control\_plane\_agent\_image\_repository) | Container image repository for the control plane agent. | `string` | `"public.ecr.aws/nullplatform/controlplane-agent"` | no | +| [control\_plane\_agent\_image\_tag](#input\_control\_plane\_agent\_image\_tag) | No default: every install pins this deliberately — see VERSIONS.md. Container image tag for the control plane agent. | `string` | n/a | yes | | [control\_plane\_enabled](#input\_control\_plane\_enabled) | Enable the control plane. | `bool` | `false` | no | | [datadog\_api\_key](#input\_datadog\_api\_key) | Datadog API key. | `string` | `""` | no | | [datadog\_enabled](#input\_datadog\_enabled) | Enable Datadog integration. | `bool` | `false` | no | @@ -139,6 +159,7 @@ resource "example_resource" "this" { | [dynatrace\_logs\_enabled](#input\_dynatrace\_logs\_enabled) | Enable log forwarding to Dynatrace. Set to false to send only metrics. | `bool` | `true` | no | | [dynatrace\_metrics\_enabled](#input\_dynatrace\_metrics\_enabled) | Enable metrics forwarding to Dynatrace. Set to false to send only logs. | `bool` | `true` | no | | [exporter\_prometheus\_port](#input\_exporter\_prometheus\_port) | Port Number to Prometheus exporter. | `string` | `"2021"` | no | +| [gateway\_api\_crd\_ref](#input\_gateway\_api\_crd\_ref) | Git ref (tag or commit) of kubernetes-sigs/gateway-api to install when install\_gateway\_v2\_crd is true. Ignored on chart versions older than the one that introduced global.gatewayApiCrdRef. Default (v1.3.0) matches what Istio 1.27 documents installing; re-check istio.io's version-pinned docs when bumping Istio. | `string` | `"v1.3.0"` | no | | [gateway\_api\_crds\_install](#input\_gateway\_api\_crds\_install) | Install Gateway API CRDs. | `bool` | `false` | no | | [gateway\_api\_enabled](#input\_gateway\_api\_enabled) | Enable the Gateway API. | `bool` | `false` | no | | [gateway\_enabled](#input\_gateway\_enabled) | Enable the HTTP gateway. | `bool` | `false` | no | @@ -171,10 +192,12 @@ resource "example_resource" "this" { | [image\_pull\_secrets\_registry](#input\_image\_pull\_secrets\_registry) | Registry URL for the image pull secret. | `string` | `""` | no | | [image\_pull\_secrets\_username](#input\_image\_pull\_secrets\_username) | Registry username. | `string` | `""` | no | | [ingressControllers](#input\_ingressControllers) | Configuración de los IngressControllers públicos y privados |
object({
public = object({
name = string
enabled = bool
scope = string
domain = string
})
private = object({
name = string
enabled = bool
scope = string
domain = string
})
})
|
{
"private": {
"domain": "",
"enabled": false,
"name": "internal",
"scope": "Internal"
},
"public": {
"domain": "",
"enabled": false,
"name": "internet-facing",
"scope": "External"
}
}
| no | -| [install\_gateway\_v2\_crd](#input\_install\_gateway\_v2\_crd) | Install Gateway API v2 CRDs. | `bool` | `false` | no | +| [install\_gateway\_v2\_crd](#input\_install\_gateway\_v2\_crd) | Install/reconcile the Gateway API CRDs (see gateway\_api\_crd\_ref) via the base chart's pre-install/pre-upgrade Job. Defaults to true so CRDs actually track gateway\_api\_crd\_ref instead of staying frozen at whatever was present on first install — matches the base chart's own default. Safe on chart versions before global.gatewayApiCrdRef too: those only install when the CRD is missing, so pre-existing CRDs from another source are left untouched. | `bool` | `true` | no | | [internal\_azure\_load\_balancer\_subnet](#input\_internal\_azure\_load\_balancer\_subnet) | Name of the subnet for the internal gateway's Azure load balancer. Empty by default, in which case Azure picks the subnet automatically. Must be the subnet's resource name (e.g. "subnet-4"), not the key it has in a subnets\_definition map. | `string` | `""` | no | | [k8s\_provider](#input\_k8s\_provider) | Cloud provider (eks, gke, aks, oke and aro). | `string` | n/a | yes | | [logging\_application\_logs\_enabled](#input\_logging\_application\_logs\_enabled) | Enable application log forwarding. Set to false to keep only http/sys metrics pipelines active across all providers. | `bool` | `true` | no | +| [logging\_controller\_image\_repository](#input\_logging\_controller\_image\_repository) | Container image repository for the logs controller DaemonSet. | `string` | `"public.ecr.aws/nullplatform/k8s-logs-controller"` | no | +| [logging\_controller\_image\_tag](#input\_logging\_controller\_image\_tag) | No default: every install pins this deliberately — see VERSIONS.md. Container image tag for the logs controller DaemonSet. | `string` | n/a | yes | | [logging\_enabled](#input\_logging\_enabled) | Enable the logging layer. | `bool` | `true` | no | | [logging\_mount\_docker\_containers](#input\_logging\_mount\_docker\_containers) | Mount Docker container log paths. Enable when using Docker container runtime (e.g. Minikube). | `bool` | `false` | no | | [loki\_bearer\_token](#input\_loki\_bearer\_token) | Loki bearer token (if applicable). | `string` | `""` | no | @@ -191,7 +214,7 @@ resource "example_resource" "this" { | [newrelic\_metrics\_enabled](#input\_newrelic\_metrics\_enabled) | Enable metrics forwarding to New Relic. Set to false to send only logs. | `bool` | `true` | no | | [newrelic\_region](#input\_newrelic\_region) | New Relic region (e.g., US, EU). | `string` | `""` | no | | [np\_api\_key](#input\_np\_api\_key) | Nullplatform API key for authentication (account level). | `string` | n/a | yes | -| [nullplatform\_base\_helm\_version](#input\_nullplatform\_base\_helm\_version) | Helm chart version for the nullplatform base. | `string` | `"2.40.0"` | no | +| [nullplatform\_base\_helm\_version](#input\_nullplatform\_base\_helm\_version) | No default: every install pins this deliberately — see VERSIONS.md. Helm chart version for the nullplatform base. | `string` | n/a | yes | | [prometheus\_enabled](#input\_prometheus\_enabled) | Enable the Prometheus exporter. | `bool` | `true` | no | | [tls\_required](#input\_tls\_required) | Whether TLS is required. | `bool` | `true` | no | @@ -211,16 +234,16 @@ resource "example_resource" "this" { diff --git a/nullplatform/cloud/aws/cloud/README.md b/nullplatform/cloud/aws/cloud/README.md index 423263f9..4fb80498 100644 --- a/nullplatform/cloud/aws/cloud/README.md +++ b/nullplatform/cloud/aws/cloud/README.md @@ -21,7 +21,7 @@ The module uses data sources aws_caller_identity and aws_region to dynamically r ```hcl module "cloud" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/aws/cloud?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/aws/cloud?ref=v8.0.0" domain_name = "your-domain-name" hosted_private_zone_id = "your-hosted-private-zone-id" diff --git a/nullplatform/cloud/aws/vpc/README.md b/nullplatform/cloud/aws/vpc/README.md index a18666c1..d573d513 100644 --- a/nullplatform/cloud/aws/vpc/README.md +++ b/nullplatform/cloud/aws/vpc/README.md @@ -20,7 +20,7 @@ The module creates a single nullplatform_provider_config resource of type aws-ne ```hcl module "vpc" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/aws/vpc?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/aws/vpc?ref=v8.0.0" nrn = "your-nrn" vpc_id = "your-vpc-id" diff --git a/nullplatform/cloud/azure/cloud/README.md b/nullplatform/cloud/azure/cloud/README.md index 9fbf7fc1..d61d05f8 100644 --- a/nullplatform/cloud/azure/cloud/README.md +++ b/nullplatform/cloud/azure/cloud/README.md @@ -22,7 +22,7 @@ The module creates a single nullplatform_provider_config resource of type 'azure ```hcl module "cloud" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/azure/cloud?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/azure/cloud?ref=v8.0.0" azure_resource_group_name = "your-azure-resource-group-name" nrn = "your-nrn" diff --git a/nullplatform/cloud/gcp/cloud/README.md b/nullplatform/cloud/gcp/cloud/README.md index aa7524f8..0897acbd 100644 --- a/nullplatform/cloud/gcp/cloud/README.md +++ b/nullplatform/cloud/gcp/cloud/README.md @@ -19,7 +19,7 @@ The module creates a single nullplatform_provider_config resource of type 'googl ```hcl module "cloud" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/gcp/cloud?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/gcp/cloud?ref=v8.0.0" domain_name = "your-domain-name" location = "your-location" diff --git a/nullplatform/cloud/oci/cloud/README.md b/nullplatform/cloud/oci/cloud/README.md index a359e811..e690620f 100644 --- a/nullplatform/cloud/oci/cloud/README.md +++ b/nullplatform/cloud/oci/cloud/README.md @@ -19,7 +19,7 @@ The module creates a single nullplatform_provider_config resource of type 'oci-c ```hcl module "cloud" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/oci/cloud?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/cloud/oci/cloud?ref=v8.0.0" account_id = "your-account-id" account_name = "your-account-name" diff --git a/nullplatform/code_repository/README.md b/nullplatform/code_repository/README.md index 61229c7c..be33cc6c 100644 --- a/nullplatform/code_repository/README.md +++ b/nullplatform/code_repository/README.md @@ -22,7 +22,7 @@ The module uses local boolean flags (is_gitlab, is_github, is_azure, is_bitbucke ```hcl module "code_repository" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v8.0.0" git_provider = "your-git-provider" nrn = "your-nrn" @@ -33,7 +33,7 @@ module "code_repository" { ```hcl module "code_repository" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v8.0.0" git_provider = "github" github_installation_id = "your-github-installation-id" # Required when git_provider = "github" @@ -46,7 +46,7 @@ module "code_repository" { ```hcl module "code_repository" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v8.0.0" git_provider = "gitlab" gitlab_access_token = "your-gitlab-access-token" # Required when git_provider = "gitlab" @@ -62,7 +62,7 @@ module "code_repository" { ```hcl module "code_repository" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v8.0.0" azure_access_token = "your-azure-access-token" # Required when git_provider = "azure" azure_agent_pool = "your-azure-agent-pool" # Required when git_provider = "azure" @@ -76,7 +76,7 @@ module "code_repository" { ```hcl module "code_repository" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/code_repository?ref=v8.0.0" bitbucket_collaborators = "your-bitbucket-collaborators" # Required when git_provider = "bitbucket" bitbucket_installation_url = "your-bitbucket-installation-url" # Required when git_provider = "bitbucket" diff --git a/nullplatform/container_orchestration/aks/README.md b/nullplatform/container_orchestration/aks/README.md index 295a2d75..2fa5a20d 100644 --- a/nullplatform/container_orchestration/aks/README.md +++ b/nullplatform/container_orchestration/aks/README.md @@ -2,31 +2,75 @@ ## Description -Configures an AKS cluster in the Nullplatform by creating a provider configuration resource that encapsulates cluster settings, gateway configuration, resource management policies, and security parameters +Configures a Nullplatform AKS provider configuration resource with cluster, gateway, resource management, security, and traffic manager settings ## Architecture -The module builds a local.attributes map that aggregates cluster metadata, gateway specs, resource limits, and security settings, then passes this JSON-encoded structure to the nullplatform_provider_config resource of type aks-configuration. Inputs like cluster_name, resource_group, and gateway names flow into the attributes map, while optional blocks for resource_management and security are conditionally included based on non-empty variables. The resulting provider configuration is registered against the given NRN in the Nullplatform. +The module constructs a set of structured locals that merge optional and required inputs into a nested attribute map, then encodes it as JSON into a single nullplatform_provider_config resource of type aks-configuration. The cluster local combines cluster_name, resource_group, namespace, and optional authentication_mode, while the gateway local merges public and optional private gateway names. Resource management, security, and object modifier locals are conditionally included only when their respective input variables are non-empty, and the final attributes map is passed to the nullplatform_provider_config resource alongside the NRN and dimensions inputs. ## Features -- Creates Nullplatform provider configuration for AKS clusters -- Configures public and optional private Application Gateway references -- Supports resource quotas for CPU/memory ratios and core limits -- Manages image pull secrets and service account mappings -- Enables traffic manager sidecar version specification -- Applies dynamic object modifiers for Kubernetes resources +- Creates a nullplatform_provider_config resource of type aks-configuration scoped to a Nullplatform NRN +- Configures AKS cluster identity with optional authentication mode selection (localAccounts, azureActiveDirectory, localandAAD) +- Configures public and optionally private Istio ingress gateway references within the provider config +- Enforces a pinned, non-moving traffic manager sidecar container version via validation +- Supports optional resource management tuning including memory/CPU ratios and millicore limits +- Supports optional Kubernetes security settings including image pull secrets and service account name +- Supports dynamic Kubernetes object modifiers for runtime patch customization ## Basic Usage ```hcl module "aks" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/aks?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/aks?ref=v8.0.0" - cluster_name = "your-cluster-name" - nrn = "your-nrn" - public_gateway_name = "your-public-gateway-name" - resource_group = "your-resource-group" + cluster_name = "your-cluster-name" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + resource_group = "your-resource-group" + traffic_manager_version = "your-traffic-manager-version" +} +``` + +### Usage with Latest Traffic Manager Version + +```hcl +module "aks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/aks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + resource_group = "your-resource-group" + traffic_manager_version = "latest" +} +``` + +### Usage with Main Traffic Manager Version + +```hcl +module "aks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/aks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + resource_group = "your-resource-group" + traffic_manager_version = "main" +} +``` + +### Usage with Master Traffic Manager Version + +```hcl +module "aks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/aks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + resource_group = "your-resource-group" + traffic_manager_version = "master" } ``` @@ -78,21 +122,22 @@ resource "example_resource" "this" { | [public\_gateway\_name](#input\_public\_gateway\_name) | Name of the public Application Gateway in AKS | `string` | n/a | yes | | [resource\_group](#input\_resource\_group) | Name of the resource group containing the AKS cluster | `string` | n/a | yes | | [service\_account\_name](#input\_service\_account\_name) | The name of the Kubernetes service account used for deployments | `string` | `""` | no | -| [traffic\_manager\_version](#input\_traffic\_manager\_version) | Tag for the traffic manager sidecar container | `string` | `""` | no | +| [traffic\_manager\_version](#input\_traffic\_manager\_version) | No default: every install pins this deliberately — see VERSIONS.md. Tag for the traffic manager sidecar container | `string` | n/a | yes | diff --git a/nullplatform/container_orchestration/eks/README.md b/nullplatform/container_orchestration/eks/README.md index 93b745fd..f8371f4a 100644 --- a/nullplatform/container_orchestration/eks/README.md +++ b/nullplatform/container_orchestration/eks/README.md @@ -2,29 +2,67 @@ ## Description -Configures Nullplatform provider settings for Amazon EKS clusters with application deployment, load balancing, and resource management capabilities +Configures a Nullplatform EKS provider configuration resource that registers an Amazon EKS cluster with the Nullplatform platform, including load balancer, networking, resource management, security, and traffic manager sidecar settings ## Architecture -Creates a nullplatform_provider_config resource with type 'eks-configuration' that aggregates cluster, balancer, network, resource management, and security settings. The module accepts EKS cluster configuration through input variables, constructs nested attribute maps using conditional logic to filter empty values, and encodes them as JSON attributes for the provider configuration. Internal locals merge cluster identity, load balancer names (public/private with additional balancers), namespace settings, resource quotas, and security configurations before passing them to the provider resource. +The module constructs a structured attributes map from input variables using Terraform locals, merging cluster identity, balancer configuration, network settings, resource management ratios, security credentials, and traffic manager sidecar parameters. A single nullplatform_provider_config resource of type eks-configuration is created, encoding the merged attributes map as JSON and binding it to a specific NRN and optional dimension set. Input variables are conditionally included in the attributes payload only when non-empty or non-null, ensuring the provider config reflects only explicitly configured values. The resource output exposes the resulting provider configuration for downstream Nullplatform platform integration. ## Features -- Configures EKS cluster identity and default Kubernetes namespace for application deployments -- Manages public and private Application Load Balancer naming with support for additional balancers beyond the 100-rule limit -- Sets ALB capacity thresholds (50-99%) to reserve slots for concurrent deployments -- Controls resource allocation ratios for memory-to-CPU, memory request-to-limit, and CPU multipliers -- Configures image pull secrets and service account associations for secure container image access -- Supports traffic manager sidecar versioning and dynamic Kubernetes object modifications +- Creates a nullplatform_provider_config resource of type eks-configuration that registers an EKS cluster with the Nullplatform platform +- Configures public and private ALB routing with support for additional load balancers beyond the 100-rule limit and configurable capacity thresholds +- Pins the traffic manager sidecar container to a fixed, explicit version tag to prevent unintended image drift on pod restarts +- Supports custom traffic manager sidecar port binding to accommodate clusters that restrict pod-to-pod traffic on port 80 +- Manages Kubernetes resource allocation ratios including memory-to-CPU ratio, memory request-to-limit ratio, and maximum milicores per pod +- Configures Kubernetes security context including image pull secrets and service account name for private registry access +- Applies dynamic Kubernetes object modifiers to patch arbitrary k8s resources at deploy time via a structured selector-action-type-value list ## Basic Usage ```hcl module "eks" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/eks?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/eks?ref=v8.0.0" - cluster_name = "your-cluster-name" - nrn = "your-nrn" + cluster_name = "your-cluster-name" + nrn = "your-nrn" + traffic_manager_version = "your-traffic-manager-version" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "eks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/eks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + traffic_manager_version = "latest" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "eks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/eks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + traffic_manager_version = "main" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "eks" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/eks?ref=v8.0.0" + + cluster_name = "your-cluster-name" + nrn = "your-nrn" + traffic_manager_version = "master" } ``` @@ -77,22 +115,24 @@ resource "example_resource" "this" { | [private\_balancer\_name](#input\_private\_balancer\_name) | The name of the private load balancer for internal traffic routing | `string` | `""` | no | | [public\_balancer\_name](#input\_public\_balancer\_name) | The name of the public-facing load balancer for external traffic routing | `string` | `""` | no | | [service\_account\_name](#input\_service\_account\_name) | The name of the Kubernetes service account used for deployments | `string` | `""` | no | -| [traffic\_manager\_version](#input\_traffic\_manager\_version) | Tag for the traffic manager sidecar container | `string` | `"latest"` | no | +| [traffic\_manager\_port](#input\_traffic\_manager\_port) | Port the traffic manager sidecar binds inside the pod. Defaults to 80 when unset. Set a different port (10080 recommended) when the cluster does not allow pod-to-pod traffic on port 80, which surfaces as a healthy pod that receives no traffic because kubelet probes are node-local and bypass the filtering. Open the port for pod-to-pod traffic before setting this value | `number` | `null` | no | +| [traffic\_manager\_version](#input\_traffic\_manager\_version) | No default: every install pins this deliberately — see VERSIONS.md. Pinned rather than tracking latest: a moving tag means a pod restart can pull a different build with no apply in between. Tag for the traffic manager sidecar container | `string` | n/a | yes | | [use\_nullplatform\_namespace](#input\_use\_nullplatform\_namespace) | When enabled, uses the nullplatform system namespace instead of a custom namespace | `bool` | `false` | no | diff --git a/nullplatform/container_orchestration/gke/README.md b/nullplatform/container_orchestration/gke/README.md index b3a6ef1c..f0b8c532 100644 --- a/nullplatform/container_orchestration/gke/README.md +++ b/nullplatform/container_orchestration/gke/README.md @@ -2,32 +2,75 @@ ## Description -Configures a GKE provider configuration resource in Nullplatform by encoding cluster, gateway, resource management, and security settings as a typed provider config +Configures a Nullplatform GKE provider configuration resource with cluster, gateway, resource management, security, and traffic manager settings ## Architecture -The module constructs a structured attributes object using locals that merge cluster identity, gateway configuration, optional resource management ratios, security settings, and object modifiers. A single nullplatform_provider_config resource of type 'gke-configuration' is created, binding the NRN and dimensions to the JSON-encoded attributes. Input variables flow into conditional merges within locals so that optional fields like private_gateway_name, service_account_name, and traffic_manager_version are only included when non-empty. The resulting resource acts as a configuration record in the Nullplatform platform for GKE cluster integration. +The module constructs a set of local values by merging optional inputs into a structured attributes map covering cluster identity, gateway configuration, resource management ratios, security settings, and traffic manager version. A single nullplatform_provider_config resource of type gke-configuration is created, receiving the NRN, dimensions, and the JSON-encoded attributes map. Optional fields such as private gateway name, gateway namespace, memory/CPU ratios, image pull secrets, service account, and object modifiers are conditionally included in the attributes only when non-empty. The resource acts as a declarative configuration registration within the Nullplatform control plane for a target GKE cluster. ## Features -- Creates a nullplatform_provider_config resource of type gke-configuration with cluster identity and location -- Configures public and optional private gateway references with namespace support -- Encodes resource management settings including memory/CPU ratios and max milicores when provided -- Attaches image pull secrets and Kubernetes service account name for secure workload identity -- Includes optional traffic manager sidecar version tagging -- Supports dynamic Kubernetes object modifiers for patching deployed resources -- Conditionally omits optional fields from the encoded attributes when left as empty defaults +- Creates a nullplatform_provider_config resource of type gke-configuration to register GKE cluster settings +- Configures cluster identity with name, location, and default application namespace +- Configures public and optional private Istio gateway references with namespace support +- Conditionally includes resource management settings such as memory/CPU ratios and max milicores +- Conditionally includes security settings including image pull secrets and Kubernetes service account name +- Pins traffic manager sidecar container to a fixed, explicit version tag +- Supports dynamic Kubernetes object modifiers for runtime patching of workload manifests ## Basic Usage ```hcl module "gke" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/gke?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/gke?ref=v8.0.0" - cluster_name = "your-cluster-name" - location = "your-location" - nrn = "your-nrn" - public_gateway_name = "your-public-gateway-name" + cluster_name = "your-cluster-name" + location = "your-location" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + traffic_manager_version = "your-traffic-manager-version" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "gke" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/gke?ref=v8.0.0" + + cluster_name = "your-cluster-name" + location = "your-location" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + traffic_manager_version = "latest" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "gke" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/gke?ref=v8.0.0" + + cluster_name = "your-cluster-name" + location = "your-location" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + traffic_manager_version = "main" +} +``` + +### Usage with Pinned Release Version + +```hcl +module "gke" { + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/gke?ref=v8.0.0" + + cluster_name = "your-cluster-name" + location = "your-location" + nrn = "your-nrn" + public_gateway_name = "your-public-gateway-name" + traffic_manager_version = "master" } ``` @@ -78,22 +121,22 @@ resource "example_resource" "this" { | [private\_gateway\_name](#input\_private\_gateway\_name) | Name of the private gateway | `string` | `""` | no | | [public\_gateway\_name](#input\_public\_gateway\_name) | Name of the public gateway | `string` | n/a | yes | | [service\_account\_name](#input\_service\_account\_name) | The name of the Kubernetes service account used for deployments | `string` | `""` | no | -| [traffic\_manager\_version](#input\_traffic\_manager\_version) | Tag for the traffic manager sidecar container | `string` | `""` | no | +| [traffic\_manager\_version](#input\_traffic\_manager\_version) | No default: every install pins this deliberately — see VERSIONS.md. Tag for the traffic manager sidecar container | `string` | n/a | yes | diff --git a/nullplatform/container_orchestration/oke/README.md b/nullplatform/container_orchestration/oke/README.md index 5b6cf510..b7737804 100644 --- a/nullplatform/container_orchestration/oke/README.md +++ b/nullplatform/container_orchestration/oke/README.md @@ -19,7 +19,7 @@ Creates a single nullplatform_provider_config resource of type 'oke' that stores ```hcl module "oke" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/oke?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/container_orchestration/oke?ref=v8.0.0" cluster_name = "your-cluster-name" nrn = "your-nrn" diff --git a/nullplatform/dimension/README.md b/nullplatform/dimension/README.md index 1daf56b7..d1ba2169 100644 --- a/nullplatform/dimension/README.md +++ b/nullplatform/dimension/README.md @@ -19,7 +19,7 @@ The module creates a nullplatform_dimension resource using the provided name, or ```hcl module "dimension" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/dimension?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/dimension?ref=v8.0.0" name = "your-name" nrn = "your-nrn" diff --git a/nullplatform/dimension_value/README.md b/nullplatform/dimension_value/README.md index e2af710b..625e3876 100644 --- a/nullplatform/dimension_value/README.md +++ b/nullplatform/dimension_value/README.md @@ -19,7 +19,7 @@ The module uses a terraform_data resource to enforce mutual-exclusivity and pres ```hcl module "dimension_value" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/dimension_value?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/dimension_value?ref=v8.0.0" dimension_id = "your-dimension-id" name = "your-name" diff --git a/nullplatform/identity-access-control/README.md b/nullplatform/identity-access-control/README.md index 158a62d6..5d9a56c5 100644 --- a/nullplatform/identity-access-control/README.md +++ b/nullplatform/identity-access-control/README.md @@ -20,7 +20,7 @@ The module creates a single nullplatform_provider_config resource named identity ```hcl module "identity-access-control" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/identity-access-control?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/identity-access-control?ref=v8.0.0" attributes = "your-attributes" nrn = "your-nrn" diff --git a/nullplatform/metrics/README.md b/nullplatform/metrics/README.md index c88b0a4d..92c13171 100644 --- a/nullplatform/metrics/README.md +++ b/nullplatform/metrics/README.md @@ -21,7 +21,7 @@ The module creates a single nullplatform_provider_config resource of type 'prome ```hcl module "metrics" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/metrics?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/metrics?ref=v8.0.0" nrn = "your-nrn" } diff --git a/nullplatform/packaged_service/README.md b/nullplatform/packaged_service/README.md index b50f09b3..539821b0 100644 --- a/nullplatform/packaged_service/README.md +++ b/nullplatform/packaged_service/README.md @@ -17,7 +17,7 @@ spec updates / republish correctly. ```hcl module "packaged_service" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/packaged_service?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/packaged_service?ref=v8.0.0" nrn = "organization=…:account=…:namespace=…" diff --git a/nullplatform/parameter_storage_configuration/README.md b/nullplatform/parameter_storage_configuration/README.md index 52bec1c2..5ee71761 100644 --- a/nullplatform/parameter_storage_configuration/README.md +++ b/nullplatform/parameter_storage_configuration/README.md @@ -20,7 +20,7 @@ The module delegates entirely to a remote `scope_configuration` module sourced f ```hcl module "parameter_storage_configuration" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_configuration?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_configuration?ref=v8.0.0" attributes = "your-attributes" np_api_key = "your-np-api-key" diff --git a/nullplatform/parameter_storage_definition/README.md b/nullplatform/parameter_storage_definition/README.md index 544a7d98..fc65f40b 100644 --- a/nullplatform/parameter_storage_definition/README.md +++ b/nullplatform/parameter_storage_definition/README.md @@ -20,7 +20,7 @@ A data.http resource fetches the raw specification template from a configurable ```hcl module "parameter_storage_definition" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_definition?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_definition?ref=v8.0.0" np_api_key = "your-np-api-key" nrn = "your-nrn" diff --git a/nullplatform/parameter_storage_definition_agent_association/README.md b/nullplatform/parameter_storage_definition_agent_association/README.md index 88030038..01bab179 100644 --- a/nullplatform/parameter_storage_definition_agent_association/README.md +++ b/nullplatform/parameter_storage_definition_agent_association/README.md @@ -21,7 +21,7 @@ The module creates a terraform_data resource to track API key changes and a null ```hcl module "parameter_storage_definition_agent_association" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_definition_agent_association?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/parameter_storage_definition_agent_association?ref=v8.0.0" api_key = "your-api-key" nrn = "your-nrn" diff --git a/nullplatform/scope_configuration/README.md b/nullplatform/scope_configuration/README.md index a3e370b9..134726ba 100644 --- a/nullplatform/scope_configuration/README.md +++ b/nullplatform/scope_configuration/README.md @@ -22,7 +22,7 @@ The module creates a single nullplatform_provider_config resource that encodes p ```hcl module "scope_configuration" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v8.0.0" nrn = "your-nrn" type = "your-type" @@ -33,7 +33,7 @@ module "scope_configuration" { ```hcl module "scope_configuration" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v8.0.0" aws_distribution = "your-aws-distribution" # Required when type = "static-files" aws_hosted_public_zone_id = "your-aws-hosted-public-zone-id" # Required when type = "static-files" @@ -52,7 +52,7 @@ module "scope_configuration" { ```hcl module "scope_configuration" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_configuration?ref=v8.0.0" lambda_null_agent_layer_arn = "your-lambda-null-agent-layer-arn" # Required when type = "aws-lambda" lambda_placeholder_image_uri = "your-lambda-placeholder-image-uri" # Required when type = "aws-lambda" diff --git a/nullplatform/scope_definition/README.md b/nullplatform/scope_definition/README.md index 1080cdf7..358fabe8 100644 --- a/nullplatform/scope_definition/README.md +++ b/nullplatform/scope_definition/README.md @@ -2,27 +2,27 @@ ## Description -Provisions a Nullplatform service specification, scope type, and action specifications by fetching and rendering gomplate templates from a remote repository, then patching the NRN with external provider configuration +Provisions a nullplatform scope definition by fetching and rendering service specification, scope type, and action specification templates from a remote repository, then wiring all resources together with metrics and logging provider configuration ## Architecture -The module fetches JSON templates via data.http resources from a configurable GitHub raw URL, processes them through data.external using gomplate and jq shell commands, and feeds the rendered outputs into nullplatform_service_specification, nullplatform_scope_type, and nullplatform_action_specification resources. A null_resource.nrn_patch uses a local-exec provisioner to invoke the np CLI with the NP_API_KEY environment variable to patch metrics and logging provider configuration on the NRN. Optionally, a nullplatform_provider_specification is created from a scope-configuration template when create_scope_configuration is true, with visibility controlled by concatenating var.nrn and var.extra_visible_to_nrns. +The module uses `data.http` to fetch Jinja/gomplate templates for service specs, scope types, and action specs from a configurable GitHub raw URL, then processes them via `data.external` shell programs invoking gomplate and jq. Core nullplatform resources (`nullplatform_service_specification`, `nullplatform_scope_type`, `nullplatform_action_specification`) are created in dependency order using the rendered template outputs, with IDs flowing downstream into scope type and action spec resources. A `null_resource` provisioner runs `np nrn patch` to register external metrics and logging providers against the NRN, and an optional `nullplatform_provider_specification` is created when `create_scope_configuration` is enabled. When `var.package` is set, `nullplatform_package` and `nullplatform_artifact` resources are also created to publish versioned package revisions. ## Features -- Fetches and renders service specification, scope type, and action templates from remote GitHub repositories using gomplate -- Creates nullplatform_service_specification with attributes, selectors, and cross-account visibility via extra_visible_to_nrns -- Creates nullplatform_scope_type linked to the service specification with provider type derived from rendered template -- Creates nullplatform_action_specification resources for each action defined in the service spec or explicitly provided via action_spec_names -- Patches the NRN with external metrics and logging provider slugs using the np CLI via null_resource local-exec -- Optionally creates nullplatform_provider_specification from scope-configuration template with override support for name collision avoidance -- Enforces precondition ensuring at least one action specification is resolved to prevent silent destruction of registered scope actions +- Fetches and renders service specification, scope type, and action specification templates from a remote GitHub repository using gomplate +- Creates nullplatform_service_specification with configurable visibility, selectors, and attributes derived from rendered templates +- Creates nullplatform_scope_type linked to the service specification with provider type resolved from the scope type template +- Creates nullplatform_action_specification resources for each action defined in the service spec or explicitly listed via action_spec_names +- Patches the NRN with external metrics and logging provider configuration using the np CLI via null_resource provisioner +- Optionally creates nullplatform_provider_specification from a scope-configuration template when create_scope_configuration is enabled +- Optionally publishes versioned nullplatform_package and nullplatform_artifact resources to pin scope definitions to immutable revisions ## Basic Usage ```hcl module "scope_definition" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_definition?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_definition?ref=v8.0.0" np_api_key = "your-np-api-key" nrn = "your-nrn" @@ -54,7 +54,7 @@ resource "example_resource" "this" { | [external](#provider\_external) | 2.3.5 | | [http](#provider\_http) | 3.5.0 | | [null](#provider\_null) | 3.2.4 | -| [nullplatform](#provider\_nullplatform) | 0.0.95 | +| [nullplatform](#provider\_nullplatform) | 0.0.99 | ## Resources @@ -79,7 +79,9 @@ resource "example_resource" "this" { | [extra\_visible\_to\_nrns](#input\_extra\_visible\_to\_nrns) | Additional NRNs to add to `visible_to` of the `nullplatform_service_specification`
and `nullplatform_provider_specification` created by this module. The base
visible\_to (the spec template's value for the service\_spec, and `[var.nrn]`
for the provider\_spec) is preserved; this list is appended.

Use case: share a scope\_definition with sibling accounts in the same
organization without duplicating it per account. Example:

extra\_visible\_to\_nrns = ["organization=1636958496"]

makes the spec consumable by every account under that organization.
Default = [] (no extra visibility, backwards compatible). | `list(string)` | `[]` | no | | [np\_api\_key](#input\_np\_api\_key) | Nullplatform API key used for executing local commands (e.g., 'np nrn patch') | `string` | n/a | yes | | [nrn](#input\_nrn) | Unique NRN identifier of the environment or resource in nullplatform | `string` | n/a | yes | -| [package](#input\_package) | Register this scope definition as a versioned PACKAGE. When set, the module
publishes a package revision whose bill of materials pins the service
specification, every action specification, and the artifacts you list —
so scopes bind to an immutable revision and later template changes never
mutate what already runs.

artifacts: each entry does ONE of:
• register a new artifact revision — set `meta` (JSON-able object, e.g.
{ registry = "ghcr.io", repository = "acme/img", digest = "sha256:…" });
• look up one registered elsewhere BY IDENTITY (no ids needed) — set
`lookup = true` + `meta` with the identity fields (e.g. registry +
repository; add digest/reference to pin a specific revision, otherwise
the latest revision is used);
• pin explicit ids — set `resource_id` + `resource_revision_id`.

Null (the default) keeps the classic module behavior — no package. |
object({
slug = optional(string) # default: the service specification slug
name = optional(string) # default: var.service_spec_name
version = string # semver of the revision this configuration publishes
default = optional(bool, true) # promote each published revision to the package default
tags = optional(map(string), {}) # release tags: name => version (requires an API with the package release-tag routes)
visible_to = optional(list(string)) # default: [var.nrn]
artifacts = optional(list(object({
name = string
type = optional(string, "oci_image") # oci_image | oras_artifact | git_repository | blob
meta = optional(any) # register (lookup=false) or find (lookup=true)
lookup = optional(bool, false) # true: resolve an EXISTING artifact by meta identity
resource_id = optional(string) # …or pin explicit ids
resource_revision_id = optional(string)
})), [])
})
| `null` | no | +| [package](#input\_package) | Register this scope definition as a versioned PACKAGE. When set, the module
publishes a package revision whose bill of materials pins the service
specification, every action specification, and the artifacts you list —
so scopes bind to an immutable revision and later template changes never
mutate what already runs.

artifacts: each entry does ONE of:
• register a new artifact revision — set `meta` (JSON-able object, e.g.
{ registry = "ghcr.io", repository = "acme/img", digest = "sha256:…" });
• look up one registered elsewhere BY IDENTITY (no ids needed) — set
`lookup = true` + `meta` with the identity fields (e.g. registry +
repository for oci\_image, or url for git\_repository); add the
type's own per-revision field to pin a specific revision (digest,
formatted "sha256:<64-hex>", for oci\_image; reference, e.g. a tag,
for git\_repository — the API rejects the other type's field name),
otherwise the latest revision is used;
• pin explicit ids — set `resource_id` + `resource_revision_id`.

For an "oci\_image" artifact (the default type), `name` defaults to
"worker-image" and meta.registry/meta.repository default to
var.package\_oci\_default\_registry/var.package\_oci\_default\_repository —
the platform's own container-scope worker image — when omitted from
`meta`. Only meta.digest needs setting on every release; every other
artifact type gets no meta defaults (their meta shape is unrelated to a
container registry).

Null (the default) keeps the classic module behavior — no package. |
object({
slug = optional(string) # default: the service specification slug
name = optional(string) # default: var.service_spec_name
version = string # semver of the revision this configuration publishes
default = optional(bool, true) # promote each published revision to the package default
tags = optional(map(string), {}) # release tags: name => version (requires an API with the package release-tag routes)
visible_to = optional(list(string)) # default: [var.nrn]
artifacts = optional(list(object({
name = optional(string, "worker-image")
type = optional(string, "oci_image") # oci_image | oras_artifact | git_repository | blob
meta = optional(any) # register (lookup=false) or find (lookup=true)
lookup = optional(bool, false) # true: resolve an EXISTING artifact by meta identity
resource_id = optional(string) # …or pin explicit ids
resource_revision_id = optional(string)
})), [])
})
| `null` | no | +| [package\_oci\_default\_registry](#input\_package\_oci\_default\_registry) | Default meta.registry for an oci\_image package artifact whose own meta omits it. See var.package's artifacts docs. | `string` | `"public.ecr.aws"` | no | +| [package\_oci\_default\_repository](#input\_package\_oci\_default\_repository) | Default meta.repository for an oci\_image package artifact whose own meta omits it — the platform's own container-scope worker image. See var.package's artifacts docs. | `string` | `"nullplatform/scopes/containers"` | no | | [repo\_path](#input\_repo\_path) | Base path to the repository used as context for gomplate template rendering | `string` | `"/root/.np/nullplatform/scopes"` | no | | [repository\_action\_templates](#input\_repository\_action\_templates) | repository of action template | `string` | `"https://raw.githubusercontent.com/nullplatform/scopes/refs/heads"` | no | | [repository\_action\_templates\_branch](#input\_repository\_action\_templates\_branch) | branch reference of action template | `string` | `"main"` | no | @@ -112,16 +114,16 @@ resource "example_resource" "this" { - -## Package (optional) - -Set `var.package` to also register this scope definition as a **versioned -package**: one revision whose bill of materials pins the service -specification, every action specification (both snapshotted automatically at -their latest revision), and your artifacts. Scopes then bind to an immutable -revision — publishing later versions never mutates what already runs. - -```hcl -module "scope_definition" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_definition?ref=" - # … the classic inputs … - - package = { - version = "1.0.0" - artifacts = [ - # find an artifact registered elsewhere (CI, `np package publish`) — no ids: - { name = "worker-image", lookup = true, - meta = { registry = "ghcr.io", repository = "acme/my-scope" } }, - # or register one right here: - { name = "helm-chart", type = "oci_image", - meta = { registry = "ghcr.io", repository = "acme/chart", digest = "sha256:…" } }, - ] - } -} -``` - -Iterate by bumping `package.version` (usually together with new artifact -metas) — each apply publishes a new revision and, with `default = true` (the -default), promotes it. See `examples/package/` for a complete, applied-and- -verified configuration. Requires a provider build with the package/artifact -resources (release pending — use `dev_overrides` meanwhile). diff --git a/nullplatform/scope_definition_agent_association/README.md b/nullplatform/scope_definition_agent_association/README.md index f2b583b1..29cdf0b8 100644 --- a/nullplatform/scope_definition_agent_association/README.md +++ b/nullplatform/scope_definition_agent_association/README.md @@ -2,27 +2,27 @@ ## Description -Creates and configures a nullplatform notification channel by fetching and processing a JSON template from a remote repository using gomplate and registering it via the nullplatform provider +Creates and configures a nullplatform notification channel from a remotely fetched template, supporting both legacy git-clone exec and worker-orchestrator package-exec delivery modes ## Architecture -The module fetches a notification channel template via the `data.http` data source from a configurable raw GitHub URL, then processes it using a `data.external` shell script that invokes gomplate with NRN, API key, and service context variables injected as environment variables. The rendered JSON is decoded in locals to extract type, source, filters, and configuration, which are passed into a `nullplatform_notification_channel` resource along with a dynamic `agent` block that conditionally injects override flags and environment variables into command data. A `terraform_data` resource tracks the API key and triggers replacement of the notification channel when it changes. +The module fetches a notification channel JSON template via the `http` data source from a configurable raw GitHub URL, then processes it using an `external` data source running `gomplate` and `jq` to inject NRN, API key, and scope metadata. The processed template drives a `nullplatform_notification_channel` resource that dynamically configures an agent block with either a legacy command passthrough or a `package-exec` command for worker-orchestrator mode. A `terraform_data` resource keyed on the API key triggers channel replacement when credentials rotate, and filters from the template are optionally merged with caller-supplied extra filters using a MongoDB-style `$and` expression. ## Features -- Fetches notification channel templates dynamically from a configurable remote GitHub repository branch -- Processes templates with gomplate to inject NRN, API key, scope specification ID, and slug at render time -- Creates a nullplatform_notification_channel resource with dynamic agent configuration including command data and tag-based selectors -- Merges base template filters with optional extra MongoDB-style filter expressions using $and composition -- Injects NP_ACTION_CONTEXT environment variable and optional overrides CLI flag into agent command data when override mode is enabled -- Triggers automatic replacement of the notification channel resource when the API key changes via terraform_data lifecycle dependency -- Supports configurable repository URL, branch reference, and service path for flexible template sourcing +- Fetches and processes notification channel templates remotely from a configurable GitHub repository using gomplate templating +- Creates nullplatform_notification_channel resources with dynamic agent configuration supporting both legacy git-clone exec and worker-orchestrator package-exec modes +- Merges base template filters with caller-supplied MongoDB-style extra filters using $and logic +- Configures agent selector tags to route channels to specific agents via tags_selectors map +- Supports custom override configurations appended to agent commands via overrides_flag when enabled_override is true +- Triggers automatic notification channel replacement when the API key changes via terraform_data lifecycle dependency +- Allows custom worker entrypoint paths overriding the default /app/packages//entrypoint convention ## Basic Usage ```hcl module "scope_definition_agent_association" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_definition_agent_association?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/scope_definition_agent_association?ref=v8.0.0" api_key = "your-api-key" nrn = "your-nrn" @@ -54,7 +54,7 @@ resource "example_resource" "this" { |------|---------| | [external](#provider\_external) | 2.3.5 | | [http](#provider\_http) | 3.5.0 | -| [nullplatform](#provider\_nullplatform) | 0.0.95 | +| [nullplatform](#provider\_nullplatform) | 0.0.99 | | [terraform](#provider\_terraform) | n/a | ## Resources @@ -69,7 +69,7 @@ resource "example_resource" "this" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [api\_key](#input\_api\_key) | API key for authenticating with the nullplatform API | `string` | n/a | yes | -| [description](#input\_description) | Description shown for the notification channel. | `string` | `""` | no | +| [description](#input\_description) | Description shown for the notification channel. | `string` | `"Routes Containers deployments agent"` | no | | [enabled\_override](#input\_enabled\_override) | Enable custom overrides for scope configurations via command line | `bool` | `false` | no | | [entrypoint](#input\_entrypoint) | Override the worker's baked entrypoint path. Defaults to /app/packages//entrypoint. | `string` | `""` | no | | [extra\_filters](#input\_extra\_filters) | Additional filter expression to merge with the base template filters using $and.
Accepts any valid MongoDB-style filter expression, including logical operators
($and, $or, $nor, $not) and comparison operators ($eq, $ne, $in, $nin, $gt,
$gte, $lt, $lte, $regex). If null, only the base template filters are applied.

Examples:
Simple equality: { "dimensions.environment" = "production" }
Comparison: { "action" = { "$in" = ["deployment:create", "deployment:update"] } }
Logical OR: { "$or" = [{ "details.namespace.slug" = "prod" }, { "details.namespace.slug" = "staging" }] }
Negation: { "$not" = { "entity\_data.status" = "failed" } }
Combined: { "$and" = [{ "action" = { "$regex" = "^deployment" } }, { "$or" = [...] }] } | `any` | `null` | no | @@ -98,16 +98,16 @@ resource "example_resource" "this" { diff --git a/nullplatform/service_definition/README.md b/nullplatform/service_definition/README.md index 0ceb4a41..3907a37c 100644 --- a/nullplatform/service_definition/README.md +++ b/nullplatform/service_definition/README.md @@ -2,31 +2,32 @@ ## Description -Registers a Nullplatform service specification with its action and link specifications by fetching JSON templates from a remote Git provider (GitHub, GitLab, Bitbucket) or local filesystem +Provisions nullplatform service, action, and link specifications by fetching JSON templates from a remote Git repository (GitHub, GitLab, or Bitbucket) or local filesystem and registering them as versioned resources ## Architecture -The module uses `data.http` resources to fetch service-spec, action, and link JSON templates from GitHub, GitLab, or Bitbucket raw/API endpoints, with provider-specific authentication headers computed in locals. Parsed templates are fed into `nullplatform_service_specification`, `nullplatform_action_specification` (one per entry in `available_actions`), and `nullplatform_link_specification` (one per entry in `available_links`) resources, all wired together via the service specification ID. When `var.package` is set, the module additionally creates `nullplatform_package` and `nullplatform_artifact` resources to publish an immutable versioned revision of the service definition. +The module uses data.http resources to fetch service-spec, action, and link JSON templates from a remote Git provider (GitHub, GitLab, or Bitbucket) using provider-specific raw URLs and auth headers, or reads them from the local filesystem when git_provider is 'local'. Parsed templates are fed into nullplatform_service_specification, nullplatform_action_specification, and nullplatform_link_specification resources, with action and link specifications depending on the service specification via explicit depends_on. When var.package is set, the module additionally creates nullplatform_package and nullplatform_artifact resources to register a versioned immutable package revision pinning all specifications and artifacts. ## Features -- Creates a nullplatform_service_specification from a remote or local JSON template with configurable visibility and dimensions -- Fetches and registers multiple nullplatform_action_specification resources dynamically from template files per action name -- Fetches and registers multiple nullplatform_link_specification resources dynamically from template files per link name -- Supports GitHub, GitLab, Bitbucket, and local filesystem as template sources with provider-specific authentication -- Configures GitHub ref resolution to support branches, tags, or raw commit SHAs via repository_ref_type -- Publishes an optional versioned nullplatform_package with artifact bill-of-materials when the package variable is set -- Outputs service specification ID, slug, and package metadata for downstream consumption +- Creates nullplatform_service_specification from a JSON template with configurable visibility, selectors, and dimensions +- Creates nullplatform_action_specification resources for each action template fetched from the repository +- Creates nullplatform_link_specification resources for each link template with scopes, assignability, and external config +- Fetches specification templates from GitHub, GitLab, or Bitbucket using provider-specific raw URLs and authentication headers +- Supports local filesystem template loading for offline or CI environments via git_provider = 'local' +- Registers versioned nullplatform_package and nullplatform_artifact resources when package configuration is provided +- Supports pinning to branches, tags, or raw commit SHAs via repository_ref_type and repository_branch variables ## Basic Usage ```hcl module "service_definition" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition?ref=v8.0.0" - nrn = "your-nrn" - service_name = "your-service-name" - service_path = "your-service-path" + nrn = "your-nrn" + repository_branch = "your-repository-branch" + service_name = "your-service-name" + service_path = "your-service-path" } ``` @@ -77,11 +78,13 @@ resource "example_resource" "this" { | [gitlab\_host](#input\_gitlab\_host) | GitLab host. Only used when git\_provider = "gitlab". Override for self-hosted instances (e.g. "gitlab.mycompany.com"). | `string` | `"gitlab.com"` | no | | [local\_specs\_path](#input\_local\_specs\_path) | Absolute path to the local service directory containing specs/. Required when git\_provider = "local". The directory must contain specs/service-spec.json.tpl and optionally specs/links/*.json.tpl and specs/actions/*.json.tpl. | `string` | `null` | no | | [nrn](#input\_nrn) | Nullplatform Resource Name (organization:account format) | `string` | n/a | yes | -| [package](#input\_package) | Register this service definition as a versioned PACKAGE. When set, the module
publishes a package revision whose bill of materials pins the service
specification, every action specification, every LINK specification, and the
artifacts you list — so consumers bind to an immutable revision and later
template changes never mutate what already runs.

artifacts: each entry does ONE of:
• register a new artifact revision — set `meta` (JSON-able object, e.g.
{ url = "https://github.com/acme/svc.git", reference = "main" } for a
git\_repository, or { registry, repository, digest } for an oci\_image);
• look up one registered elsewhere BY IDENTITY (no ids needed) — set
`lookup = true` + `meta` with the identity fields (add digest/reference
to pin a specific revision, otherwise the latest revision is used);
• pin explicit ids — set `resource_id` + `resource_revision_id`.

Null (the default) keeps the classic module behavior — no package. |
object({
slug = optional(string) # default: the service specification slug
name = optional(string) # default: var.service_name
version = string # semver of the revision this configuration publishes
default = optional(bool, true) # promote each published revision to the package default
tags = optional(map(string), {}) # release tags: name => version (requires an API with the package release-tag routes)
visible_to = optional(list(string)) # default: [var.nrn]
artifacts = optional(list(object({
name = string
type = optional(string, "oci_image") # oci_image | oras_artifact | git_repository | blob
meta = optional(any) # register (lookup=false) or find (lookup=true)
lookup = optional(bool, false) # true: resolve an EXISTING artifact by meta identity
resource_id = optional(string) # …or pin explicit ids
resource_revision_id = optional(string)
})), [])
})
| `null` | no | -| [repository\_branch](#input\_repository\_branch) | Branch of the service spec repository to use. Must be a short branch name (e.g. "main"), not a full ref. | `string` | `"main"` | no | +| [package](#input\_package) | Register this service definition as a versioned PACKAGE. When set, the module
publishes a package revision whose bill of materials pins the service
specification, every action specification, every LINK specification, and the
artifacts you list — so consumers bind to an immutable revision and later
template changes never mutate what already runs.

artifacts: each entry does ONE of:
• register a new artifact revision — set `meta` (JSON-able object, e.g.
{ url = "https://github.com/acme/svc.git", reference = "main" } for a
git\_repository, or { registry, repository, digest } for an oci\_image);
• look up one registered elsewhere BY IDENTITY (no ids needed) — set
`lookup = true` + `meta` with the identity fields (url for
git\_repository, or registry+repository for oci\_image); add the
type's own per-revision field to pin a specific revision (reference,
e.g. a tag, for git\_repository; digest, formatted "sha256:<64-hex>",
for oci\_image — the API rejects the other type's field name),
otherwise the latest revision is used;
• pin explicit ids — set `resource_id` + `resource_revision_id`.

An artifact's `name` defaults to "impl" and `type` to "git\_repository" —
a service package is typically a single artifact pointing at the
service's own implementation repo, so only `meta` (url/reference) needs
setting on every release.

For an artifact with `type = "oci_image"` (opt-in — not the default
here), meta.registry/meta.repository default to
var.package\_oci\_default\_registry/var.package\_oci\_default\_repository
when omitted from `meta`. Only meta.digest needs setting on every
release in that case; every other artifact type gets no meta defaults
(their meta shape is unrelated to a container registry).

Null (the default) keeps the classic module behavior — no package. |
object({
slug = optional(string) # default: the service specification slug
name = optional(string) # default: var.service_name
version = string # semver of the revision this configuration publishes
default = optional(bool, true) # promote each published revision to the package default
tags = optional(map(string), {}) # release tags: name => version (requires an API with the package release-tag routes)
visible_to = optional(list(string)) # default: [var.nrn]
artifacts = optional(list(object({
name = optional(string, "impl") # default: a single service-implementation artifact
type = optional(string, "git_repository") # oci_image | oras_artifact | git_repository | blob
meta = optional(any) # register (lookup=false) or find (lookup=true)
lookup = optional(bool, false) # true: resolve an EXISTING artifact by meta identity
resource_id = optional(string) # …or pin explicit ids
resource_revision_id = optional(string)
})), [])
})
| `null` | no | +| [package\_oci\_default\_registry](#input\_package\_oci\_default\_registry) | Default meta.registry for an oci\_image package artifact whose own meta omits it. See var.package's artifacts docs. | `string` | `"public.ecr.aws"` | no | +| [package\_oci\_default\_repository](#input\_package\_oci\_default\_repository) | Default meta.repository for an oci\_image package artifact whose own meta omits it. See var.package's artifacts docs. | `string` | `"nullplatform/scopes/containers"` | no | +| [repository\_branch](#input\_repository\_branch) | Git ref of the service spec repository to read, as a short name and not a full ref
(e.g. "v1.4.0"). No default and no recommended value: which spec repository an install
points at is its own choice, so there is no version anyone could pick for it.

Combine with repository\_ref\_type, which selects the namespace this name lives in. | `string` | n/a | yes | | [repository\_name](#input\_repository\_name) | Repository name containing the service spec templates. | `string` | `"service"` | no | | [repository\_org](#input\_repository\_org) | GitHub organization or GitLab group owning the service spec repository. | `string` | `"nullplatform"` | no | -| [repository\_ref\_type](#input\_repository\_ref\_type) | Git ref namespace for `repository_branch` on GitHub: "heads" for a branch, "tags" for a tag, or "" to treat it as a raw commit SHA. Defaults to "heads", preserving previous behaviour. | `string` | `"heads"` | no | +| [repository\_ref\_type](#input\_repository\_ref\_type) | Git ref namespace for `repository_branch` on GitHub: "heads" for a branch, "tags" for a tag, or "" to treat it as a raw commit SHA. Defaults to "heads", preserving previous behaviour. | `string` | `"tags"` | no | | [repository\_token](#input\_repository\_token) | Access token for private repositories. GitHub: personal access token or fine-grained token. GitLab: Personal Access Token (PAT) with read\_api scope. | `string` | `null` | no | | [service\_name](#input\_service\_name) | Name of the scope type to be created | `string` | n/a | yes | | [service\_path](#input\_service\_path) | Path within the repository for the specific service (e.g., databases/postgres/k8s) | `string` | n/a | yes | @@ -101,16 +104,16 @@ resource "example_resource" "this" { diff --git a/nullplatform/service_definition_agent_association/README.md b/nullplatform/service_definition_agent_association/README.md index d0e1a86f..c8e5ee5e 100644 --- a/nullplatform/service_definition_agent_association/README.md +++ b/nullplatform/service_definition_agent_association/README.md @@ -2,32 +2,30 @@ ## Description -Creates a nullplatform notification channel configured with an agent that executes a service entrypoint command from a cloned repository +Creates a nullplatform notification channel configured with an agent that routes commands to either a worker-orchestrator (package-exec) or a legacy git-clone exec handler based on the deployment mode ## Architecture -The module creates a terraform_data resource to track API key changes as a lifecycle trigger, and a nullplatform_notification_channel resource that embeds an agent configuration block. The agent configuration wires var.api_key for authentication, constructs a dynamic cmdline path from var.base_clone_path, var.repository_service_spec_repo, and var.service_path, and uses var.tags_selectors to filter target agents. A replace_triggered_by lifecycle rule on the terraform_data resource forces replacement of the notification channel whenever the API key changes. +The module creates a `terraform_data` resource to track API key changes and trigger replacement of the main `nullplatform_notification_channel` resource when the key rotates. The `nullplatform_notification_channel` resource is configured with an embedded agent block that conditionally sets the command type to either `package-exec` (worker orchestrator mode) or `exec` (legacy git-clone mode) based on `var.worker_orchestrator`. Lifecycle preconditions enforce that `package_slug` is provided in worker mode and `repository_service_spec_repo` is provided in legacy mode, while a `replace_triggered_by` dependency ensures the channel is recreated whenever the API key changes. ## Features -- Creates a nullplatform_notification_channel with embedded agent executor configuration -- Constructs a dynamic entrypoint command path from base clone path, repository name, and service subdirectory -- Configures agent selector filtering using a map of tag key-value pairs -- Applies service specification slug filtering via a JSON-encoded OR filter on the notification channel -- Triggers automatic channel replacement when the API key value changes using terraform_data lifecycle tracking -- Supports optional service path suffix for multi-service repositories -- Passes configurable arguments and notification context environment variables to the agent entrypoint +- Creates a nullplatform_notification_channel with agent-based command routing for service notifications +- Supports worker-orchestrator mode using package-exec commands with baked entrypoints from published NP packages +- Supports legacy git-clone exec mode using repository-based entrypoint paths for agent command execution +- Configures agent tag selectors to target specific agents for notification channel routing +- Applies service specification slug filters to scope notifications to matching services +- Triggers automatic channel replacement via terraform_data when the API key is rotated +- Enforces preconditions to validate required variables based on the selected orchestration mode ## Basic Usage ```hcl module "service_definition_agent_association" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition_agent_association?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition_agent_association?ref=v8.0.0" - api_key = "your-api-key" - repository_service_spec_repo = "your-repository-service-spec-repo" - service_path = "your-service-path" - tags_selectors = "your-tags-selectors" + api_key = "your-api-key" + tags_selectors = "your-tags-selectors" } ``` @@ -65,17 +63,20 @@ resource "example_resource" "this" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [agent\_arguments](#input\_agent\_arguments) | Arguments to pass to the agent entrypoint command | `list(string)` | `[]` | no | +| [agent\_arguments](#input\_agent\_arguments) | Arguments to pass to the agent entrypoint command. Unused when worker\_orchestrator = true. | `list(string)` | `[]` | no | | [api\_key](#input\_api\_key) | API key for authenticating with the nullplatform API | `string` | n/a | yes | -| [base\_clone\_path](#input\_base\_clone\_path) | Base path where the service repository is cloned inside the agent pod | `string` | `"/root/.np"` | no | +| [base\_clone\_path](#input\_base\_clone\_path) | Base path where the service repository is cloned inside the agent pod. Unused when worker\_orchestrator = true. | `string` | `"/home/agent/.np"` | no | | [channel\_sources](#input\_channel\_sources) | List of sources for the notification channel (e.g., ['monitoring', 'alerts']) | `list(string)` |
[
"service"
]
| no | | [channel\_type](#input\_channel\_type) | Type of the notification channel (e.g., 'agent') | `string` | `"agent"` | no | | [description](#input\_description) | Description shown for the notification channel. | `string` | `""` | no | +| [entrypoint](#input\_entrypoint) | Override the worker's baked entrypoint path. Defaults to /app/packages//entrypoint. | `string` | `""` | no | | [nrn](#input\_nrn) | Nullplatform Resource Name (organization:account format) | `string` | `null` | no | -| [repository\_service\_spec\_repo](#input\_repository\_service\_spec\_repo) | GitHub repository name containing the service specs (used to build the agent cmdline path) | `string` | n/a | yes | -| [service\_path](#input\_service\_path) | Path to the service directory within the repository (e.g., databases/postgres/k8s) | `string` | n/a | yes | +| [package\_slug](#input\_package\_slug) | Package/service slug — the package-exec NP\_PLUGIN and default entrypoint path. Required when worker\_orchestrator = true. | `string` | `""` | no | +| [repository\_service\_spec\_repo](#input\_repository\_service\_spec\_repo) | GitHub repository name containing the service specs (used to build the agent cmdline path). Required when worker\_orchestrator = false; unused (the worker's baked entrypoint is used instead) when true. | `string` | `""` | no | +| [service\_path](#input\_service\_path) | Path to the service directory within the repository (e.g., databases/postgres/k8s). Only consulted when worker\_orchestrator = false — empty omits the path segment. | `string` | `""` | no | | [service\_specification\_slug](#input\_service\_specification\_slug) | The slug of the service definition | `string` | `null` | no | | [tags\_selectors](#input\_tags\_selectors) | Map of tags used to select and filter agents | `map(string)` | n/a | yes | +| [worker\_orchestrator](#input\_worker\_orchestrator) | Emit a worker-orchestrator (package-exec) channel instead of the legacy
git-clone exec channel. When true, the channel routes package-exec commands
to an agent that spawns the package's worker image and runs its baked
entrypoint — matching what `np package publish` registers. Requires
package\_slug; set tags\_selectors to select the agent (e.g. {package = slug}). | `bool` | `false` | no | ## Outputs @@ -87,16 +88,16 @@ resource "example_resource" "this" { diff --git a/nullplatform/users/README.md b/nullplatform/users/README.md index 5764a1ef..408a2ada 100644 --- a/nullplatform/users/README.md +++ b/nullplatform/users/README.md @@ -21,7 +21,7 @@ The module iterates over a map of user definitions using `nullplatform_user` res ```hcl module "users" { - source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/users?ref=v7.1.0" + source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/users?ref=v8.0.0" nullplatform_users = "your-nullplatform-users" }