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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions nullplatform/cloud/aws/cloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ resource "example_resource" "this" {
| <a name="input_dimensions"></a> [dimensions](#input\_dimensions) | Map of dimension values to configure nullplatform | `map(string)` | `{}` | no |
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Domain name for the configuration | `string` | n/a | yes |
| <a name="input_hosted_private_zone_id"></a> [hosted\_private\_zone\_id](#input\_hosted\_private\_zone\_id) | Hosted zone ID for private DNS | `string` | n/a | yes |
| <a name="input_hosted_public_zone_id"></a> [hosted\_public\_zone\_id](#input\_hosted\_public\_zone\_id) | Hosted zone ID for public DNS | `string` | n/a | yes |
| <a name="input_hosted_public_zone_id"></a> [hosted\_public\_zone\_id](#input\_hosted\_public\_zone\_id) | Hosted zone ID for public DNS. Leave empty for private-only installs: when empty it is omitted from the provider config payload (the API rejects an empty string). | `string` | `""` | no |
| <a name="input_include_environment"></a> [include\_environment](#input\_include\_environment) | Whether to use Environment as a default dimension | `bool` | `true` | no |
| <a name="input_nrn"></a> [nrn](#input\_nrn) | Identifier Nullplatform Resources Name | `string` | n/a | yes |
| <a name="input_scope_manager_assume_role"></a> [scope\_manager\_assume\_role](#input\_scope\_manager\_assume\_role) | ARN of the IAM role for scope and deploy manager | `string` | `"arn:aws:iam::283477532906:role/scope_and_deploy_manager"` | no |
Expand All @@ -80,7 +80,7 @@ resource "example_resource" "this" {
"features": [
"Creates a Nullplatform AWS provider configuration resource linking account identity and region",
"Dynamically resolves current AWS account ID and region using data sources",
"Configures both private and public Route53 hosted zone IDs for DNS integration",
"Configures the private Route53 hosted zone ID for DNS integration; the public zone is optional and omitted for private-only installs",
"Supports configurable dimension maps for multi-environment Nullplatform scoping",
"Optionally includes account name in domain configuration via application_domain flag"
],
Expand All @@ -102,8 +102,8 @@ resource "example_resource" "this" {
},
{
"name": "hosted_public_zone_id",
"description": "Hosted zone ID for public DNS",
"required": true
"description": "Hosted zone ID for public DNS. Leave empty for private-only installs: when empty it is omitted from the provider config payload (the API rejects an empty string).",
"required": false
},
{
"name": "scope_manager_assume_role",
Expand Down
25 changes: 18 additions & 7 deletions nullplatform/cloud/aws/cloud/main.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
locals {
# La API de nullplatform valida hosted_public_zone_id con ^Z[A-Z0-9]{10,}$
# (verificado empíricamente) y rechaza el string vacío. Se incluye en el payload
# sólo cuando tiene valor → habilita instalaciones private-only (sin zona pública).
# El guard != null es defensivo (el default es "", pero un módulo caller podría
# pasar null explícitamente); la API no distingue null de "".
networking = merge(
{
application_domain = var.application_domain,
domain_name = var.domain_name
hosted_zone_id = var.hosted_private_zone_id
},
var.hosted_public_zone_id != null && var.hosted_public_zone_id != "" ? { hosted_public_zone_id = var.hosted_public_zone_id } : {}
)
}

resource "nullplatform_provider_config" "aws" {
provider = nullplatform
nrn = var.nrn
Expand All @@ -8,11 +24,6 @@ resource "nullplatform_provider_config" "aws" {
id = data.aws_caller_identity.current.id
region = data.aws_region.current.region
}
networking = {
application_domain = var.application_domain,
domain_name = var.domain_name
hosted_zone_id = var.hosted_private_zone_id
hosted_public_zone_id = var.hosted_public_zone_id
}
networking = local.networking
})
}
}
53 changes: 53 additions & 0 deletions nullplatform/cloud/aws/cloud/tests/aws_cloud.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,56 @@ run "attributes_contain_networking" {
error_message = "Attributes should contain the public hosted zone ID"
}
}

run "private_only_omits_public_zone" {
command = plan

variables {
hosted_public_zone_id = ""
}

assert {
condition = !strcontains(nullplatform_provider_config.aws.attributes, "hosted_public_zone_id")
error_message = "hosted_public_zone_id must be omitted from the payload when empty (private-only); the API rejects an empty string"
}

assert {
condition = strcontains(nullplatform_provider_config.aws.attributes, "Z1234567890PRIV")
error_message = "Private hosted zone ID must still be present in private-only mode"
}

assert {
condition = strcontains(nullplatform_provider_config.aws.attributes, "example.com")
error_message = "domain_name must still be present in private-only mode"
}
}

run "private_only_omits_public_zone_when_null" {
command = plan

variables {
hosted_public_zone_id = null
}

assert {
condition = !strcontains(nullplatform_provider_config.aws.attributes, "hosted_public_zone_id")
error_message = "hosted_public_zone_id must be omitted from the payload when null (private-only)"
}

assert {
condition = strcontains(nullplatform_provider_config.aws.attributes, "Z1234567890PRIV")
error_message = "Private hosted zone ID must still be present when public zone is null"
}
}

run "rejects_malformed_public_zone_id" {
command = plan

variables {
hosted_public_zone_id = "not-a-zone-id"
}

expect_failures = [
var.hosted_public_zone_id,
]
}
8 changes: 7 additions & 1 deletion nullplatform/cloud/aws/cloud/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ variable "hosted_private_zone_id" {
}

variable "hosted_public_zone_id" {
description = "Hosted zone ID for public DNS"
description = "Hosted zone ID for public DNS. Leave empty for private-only installs: when empty it is omitted from the provider config payload (the API rejects an empty string)."
type = string
default = ""

validation {
condition = var.hosted_public_zone_id == null || var.hosted_public_zone_id == "" || can(regex("^Z[A-Z0-9]{10,}$", var.hosted_public_zone_id))
error_message = "hosted_public_zone_id must be empty/null for private-only, or a valid Route53 hosted zone ID (^Z[A-Z0-9]{10,}$)."
}
}

variable "dimensions" {
Expand Down