Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ myip-default
__pycache__/
upgrade_status.json
.coverage
PLAN_*.md

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ The following table lists the _latest_ DSF Kit releases, their release date and
<td>TBD</td>
<td>
1. Added internal support for DRA version 15.3. Set the variable ‘dra_version’ to 15.3 to use it.
<br/>2. Added optional DNS CNAME support for AWS POC examples (dsf_deployment, sonar_basic_deployment, sonar_hadr_deployment). When configured, creates friendly DNS names for public-facing instances via Route53 cross-account. Set the 'dns_zone_domain' and optionally 'dns_route53_role_arn' and 'dns_route53_zone_id' variables to enable it. Disabled by default.
</td>
</tr>

Expand Down
70 changes: 70 additions & 0 deletions examples/aws/poc/dsf_deployment/dns.tf
Comment thread
elsegev marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
##############################
#### DNS / CNAME ####
##############################
#
# Creates CNAME records in Route53 for all public-facing instances.
# This enables access through zScaler Dedicated IP which blocks direct
# AWS public IP/DNS access.
#
# Usage:
# dns_zone_domain only → outputs show records to create manually
# dns_zone_domain + role_arn → records auto-created in Route53

# Cross-account Route53 provider
# When dns_route53_role_arn is null, assume_role is effectively skipped.
# All resources using this provider have count/for_each gated behind dns_auto_create,
# so no Route53 API calls are made when DNS is not configured.
provider "aws" {
alias = "dns"
assume_role {
role_arn = var.dns_route53_role_arn
}
}

locals {
dns_enabled = var.dns_zone_domain != null
dns_auto_create = var.dns_zone_domain != null && var.dns_route53_role_arn != null && var.dns_route53_zone_id != null

# Build map: static-key => target-public-dns
# Keys MUST be known at plan time for for_each. We use simple suffixes
# ("hub", "mx", etc.) and construct the full CNAME name in the resource.
dns_record_targets = local.dns_enabled ? merge(
var.enable_sonar ? {
"hub" = module.hub_main[0].public_dns
} : {},
var.enable_sonar && var.hub_hadr ? {
"hub-dr" = module.hub_dr[0].public_dns
} : {},
var.enable_dam ? {
"mx" = module.mx[0].public_dns
} : {},
var.enable_dra ? {
"dra-admin" = module.dra_admin[0].public_dns
} : {},
var.enable_ciphertrust ? {
for idx, val in module.ciphertrust_manager :
"cm-${idx}" => val.public_dns
} : {},
var.enable_ciphertrust ? {
for key, val in module.cte_ddc_agents :
key => val.public_dns
} : {},
) : {}

# DNS hostnames for use in outputs
# When DNS is configured, returns CNAME hostname; otherwise returns original public_dns
dns_hub_main = local.dns_enabled ? "${local.deployment_name_salted}-hub.${var.dns_zone_domain}" : try(module.hub_main[0].public_dns, null)
dns_hub_dr = local.dns_enabled ? "${local.deployment_name_salted}-hub-dr.${var.dns_zone_domain}" : try(module.hub_dr[0].public_dns, null)
dns_mx = local.dns_enabled ? "${local.deployment_name_salted}-mx.${var.dns_zone_domain}" : try(module.mx[0].public_dns, null)
dns_dra_admin = local.dns_enabled ? "${local.deployment_name_salted}-dra-admin.${var.dns_zone_domain}" : try(module.dra_admin[0].public_dns, null)
}

resource "aws_route53_record" "dns" {
for_each = local.dns_auto_create ? local.dns_record_targets : {}
provider = aws.dns
zone_id = var.dns_route53_zone_id
name = "${local.deployment_name_salted}-${each.key}"
type = "CNAME"
ttl = 300
records = [each.value]
}
50 changes: 31 additions & 19 deletions examples/aws/poc/dsf_deployment/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ output "sonar" {
jsonar_uid = try(module.hub_main[0].jsonar_uid, null)
display_name = try(module.hub_main[0].display_name, null)
role_arn = try(module.hub_main[0].iam_role, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.hub_main[0].ssh_user}@${module.hub_main[0].public_dns}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.hub_main[0].ssh_user}@${local.dns_hub_main}", null)
tokens = nonsensitive(module.hub_main[0].access_tokens)
}
hub_dr = var.hub_hadr ? {
Expand All @@ -40,7 +40,7 @@ output "sonar" {
jsonar_uid = try(module.hub_dr[0].jsonar_uid, null)
display_name = try(module.hub_dr[0].display_name, null)
role_arn = try(module.hub_dr[0].iam_role, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.hub_dr[0].ssh_user}@${module.hub_dr[0].public_dns}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.hub_dr[0].ssh_user}@${local.dns_hub_dr}", null)
} : null
agentless_gw_main = [
for idx, val in module.agentless_gw_main :
Expand All @@ -50,7 +50,7 @@ output "sonar" {
jsonar_uid = try(val.jsonar_uid, null)
display_name = try(val.display_name, null)
role_arn = try(val.iam_role, null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.hub_main[0].ssh_user}@${module.hub_main[0].public_ip}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.hub_main[0].ssh_user}@${local.dns_hub_main}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
}
]
agentless_gw_dr = var.agentless_gw_hadr ? [
Expand All @@ -61,7 +61,7 @@ output "sonar" {
jsonar_uid = try(val.jsonar_uid, null)
display_name = try(val.display_name, null)
role_arn = try(val.iam_role, null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.hub_main[0].ssh_user}@${module.hub_main[0].public_ip}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.hub_main[0].ssh_user}@${local.dns_hub_main}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
}
] : []
} : null
Expand All @@ -76,8 +76,8 @@ output "dam" {
private_dns = try(module.mx[0].private_dns, null)
display_name = try(module.mx[0].display_name, null)
role_arn = try(module.mx[0].iam_role, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.mx[0].ssh_user}@${module.mx[0].public_dns}", null)
public_url = try(join("", ["https://", module.mx[0].public_dns, ":8083/"]), null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.mx[0].ssh_user}@${local.dns_mx}", null)
public_url = try(join("", ["https://", local.dns_mx, ":8083/"]), null)
private_url = try(join("", ["https://", module.mx[0].private_dns, ":8083/"]), null)
password = nonsensitive(local.password)
user = module.mx[0].web_console_user
Expand All @@ -92,7 +92,7 @@ output "dam" {
display_name = try(val.display_name, null)
role_arn = try(val.iam_role, null)
group_id = try(val.group_id, null)
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.mx[0].ssh_user}@${module.mx[0].public_ip}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.mx[0].ssh_user}@${local.dns_mx}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
large_scale_mode = val.large_scale_mode
}
]
Expand All @@ -108,14 +108,14 @@ output "dra" {
private_dns = try(module.dra_admin[0].private_dns, null)
display_name = try(module.dra_admin[0].display_name, null)
role_arn = try(module.dra_admin[0].iam_role, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.dra_admin[0].ssh_user}@${module.dra_admin[0].public_dns}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.dra_admin[0].ssh_user}@${local.dns_dra_admin}", null)
}
analytics = [
for idx, val in module.dra_analytics : {
private_ip = val.private_ip
private_dns = val.private_dns
archiver_user = val.archiver_user
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.dra_admin[0].ssh_user}@${module.dra_admin[0].public_ip}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.dra_admin[0].ssh_user}@${local.dns_dra_admin}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
}
]
} : null
Expand All @@ -129,10 +129,10 @@ output "ciphertrust" {
private_dns = try(val.private_dns, null)
public_ip = try(val.public_ip, null)
public_dns = try(val.public_dns, null)
public_url = try(join("", ["https://", val.public_dns]), null)
public_url = try(join("", ["https://", local.dns_enabled ? "${local.deployment_name_salted}-cm-${idx}.${var.dns_zone_domain}" : val.public_dns]), null)
private_url = try(join("", ["https://", val.private_dns]), null)
display_name = try(val.display_name, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${val.ssh_user}@${val.public_dns}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${val.ssh_user}@${local.dns_enabled ? "${local.deployment_name_salted}-cm-${idx}.${var.dns_zone_domain}" : val.public_dns}", null)
}
]
} : null
Expand All @@ -148,7 +148,7 @@ output "cte_ddc_agents" {
public_ip = module.cte_ddc_agents[val.id].public_ip
public_dns = module.cte_ddc_agents[val.id].public_dns
display_name = try(module.cte_ddc_agents[val.id].display_name, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${module.cte_ddc_agents[val.id].public_ip}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${local.dns_enabled ? "${local.deployment_name_salted}-${val.id}.${var.dns_zone_domain}" : module.cte_ddc_agents[val.id].public_ip}", null)
}
]
ddc_agents = [
Expand All @@ -159,7 +159,7 @@ output "cte_ddc_agents" {
public_ip = module.cte_ddc_agents[val.id].public_ip
public_dns = module.cte_ddc_agents[val.id].public_dns
display_name = try(module.cte_ddc_agents[val.id].display_name, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${module.cte_ddc_agents[val.id].public_ip}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${local.dns_enabled ? "${local.deployment_name_salted}-${val.id}.${var.dns_zone_domain}" : module.cte_ddc_agents[val.id].public_ip}", null)
}
]
cte_ddc_agents = [
Expand All @@ -170,7 +170,7 @@ output "cte_ddc_agents" {
public_ip = module.cte_ddc_agents[val.id].public_ip
public_dns = module.cte_ddc_agents[val.id].public_dns
display_name = try(module.cte_ddc_agents[val.id].display_name, null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${module.cte_ddc_agents[val.id].public_ip}", null)
ssh_command = try("ssh -i ${local.private_key_file_path} ${module.cte_ddc_agents[val.id].ssh_user}@${local.dns_enabled ? "${local.deployment_name_salted}-${val.id}.${var.dns_zone_domain}" : module.cte_ddc_agents[val.id].public_ip}", null)
}
]
} : null
Expand All @@ -185,7 +185,7 @@ output "audit_sources" {
private_dns = val.private_dns
db_type = val.db_type
os_type = val.os_type
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.mx[0].ssh_user}@${module.mx[0].public_ip}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o UserKnownHostsFile=/dev/null -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${local.private_key_file_path} -W %h:%p ${module.mx[0].ssh_user}@${local.dns_mx}' -i ${local.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
}
]
agentless_sources = var.enable_sonar ? {
Expand All @@ -200,21 +200,21 @@ output "web_console_dsf_hub" {
value = try({
user = module.hub_main[0].web_console_user
password = nonsensitive(local.password)
public_url = join("", ["https://", module.hub_main[0].public_dns, ":8443/"])
public_url = join("", ["https://", local.dns_hub_main, ":8443/"])
private_url = join("", ["https://", module.hub_main[0].private_dns, ":8443/"])
}, null)
}

output "web_console_dra" {
value = try({
public_url = join("", ["https://", module.dra_admin[0].public_dns, ":8443/"])
public_url = join("", ["https://", local.dns_dra_admin, ":8443/"])
private_url = join("", ["https://", module.dra_admin[0].private_dns, ":8443/"])
}, null)
}

output "web_console_dam" {
value = try({
public_url = join("", ["https://", module.mx[0].public_dns, ":8083/"])
public_url = join("", ["https://", local.dns_mx, ":8083/"])
private_url = join("", ["https://", module.mx[0].private_dns, ":8083/"])
password = nonsensitive(local.password)
user = module.mx[0].web_console_user
Expand All @@ -223,13 +223,25 @@ output "web_console_dam" {

output "web_console_ciphertrust" {
value = try({
public_url = join("", ["https://", module.ciphertrust_manager[0].public_dns])
public_url = join("", ["https://", local.dns_enabled ? "${local.deployment_name_salted}-cm-0.${var.dns_zone_domain}" : module.ciphertrust_manager[0].public_dns])
private_url = join("", ["https://", module.ciphertrust_manager[0].private_dns])
password = nonsensitive(local.password)
user = local.ciphertrust_manager_web_console_username
}, null)
}

output "dns_records" {
description = "DNS CNAME records for all public-facing instances. Shows records that need to exist for zScaler access."
value = local.dns_enabled ? {
for suffix, target in local.dns_record_targets :
"${local.deployment_name_salted}-${suffix}.${var.dns_zone_domain}" => {
type = "CNAME"
target = target
auto_created = local.dns_auto_create
}
} : null
Comment thread
elsegev marked this conversation as resolved.
Outdated
}

output "fam_classification_integration_resources" {
value = try({
scan_results_bucket_name = aws_s3_bucket.fam_scan_results_bucket[0].id
Expand Down
24 changes: 23 additions & 1 deletion examples/aws/poc/dsf_deployment/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,26 @@ variable "create_fam_classification_integration_resources" {
type = bool
default = false
description = "Whether to create the AWS S3 and SQS resources required for FAM classification integration between Hub and CipherTrust."
}
}

##############################
#### DNS variables ####
##############################

variable "dns_zone_domain" {
type = string
default = null
description = "DNS zone domain for creating CNAME records for public instances (e.g., 'clouddev.cdi-csp.thalesgroup.com'). When set, outputs include the DNS records to create. Customers should leave this null."
Comment thread
elsegev marked this conversation as resolved.
Outdated
}

variable "dns_route53_role_arn" {
type = string
default = null
description = "IAM role ARN for cross-account Route53 access. When set along with dns_zone_domain and dns_route53_zone_id, CNAME records are automatically created in Route53."
}

variable "dns_route53_zone_id" {
type = string
default = null
description = "Route53 hosted zone ID for the dns_zone_domain. Required for auto-creating CNAME records."
}
46 changes: 46 additions & 0 deletions examples/aws/poc/sonar_basic_deployment/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
##############################
#### DNS / CNAME ####
##############################
#
# Creates CNAME records in Route53 for public-facing instances.
# This enables access through zScaler Dedicated IP which blocks direct
# AWS public IP/DNS access.
#
# Usage:
# dns_zone_domain only → outputs show records to create manually
# dns_zone_domain + role_arn → records auto-created in Route53

# Cross-account Route53 provider
# When dns_route53_role_arn is null, assume_role is effectively skipped.
# All resources using this provider have count/for_each gated behind dns_auto_create,
# so no Route53 API calls are made when DNS is not configured.
provider "aws" {
alias = "dns"
assume_role {
role_arn = var.dns_route53_role_arn
}
}

locals {
dns_enabled = var.dns_zone_domain != null
dns_auto_create = var.dns_zone_domain != null && var.dns_route53_role_arn != null && var.dns_route53_zone_id != null

# Build map: static-key => target-public-dns
dns_record_targets = local.dns_enabled ? {
"hub" = module.hub.public_dns
} : {}

# DNS hostname for use in outputs
# When DNS is configured, returns CNAME hostname; otherwise returns original public_dns
dns_hub = local.dns_enabled ? "${local.deployment_name_salted}-hub.${var.dns_zone_domain}" : module.hub.public_dns
}

resource "aws_route53_record" "dns" {
for_each = local.dns_auto_create ? local.dns_record_targets : {}
provider = aws.dns
zone_id = var.dns_route53_zone_id
name = "${local.deployment_name_salted}-${each.key}"
type = "CNAME"
ttl = 300
records = [each.value]
}
20 changes: 16 additions & 4 deletions examples/aws/poc/sonar_basic_deployment/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ output "dsf_agentless_gw" {
jsonar_uid = try(val.jsonar_uid, null)
display_name = try(val.display_name, null)
role_arn = try(val.iam_role, null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${module.key_pair.private_key_file_path} -W %h:%p ${module.hub.ssh_user}@${module.hub.public_ip}' -i ${module.key_pair.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
ssh_command = try("ssh -o ProxyCommand='ssh -o UserKnownHostsFile=/dev/null -i ${module.key_pair.private_key_file_path} -W %h:%p ${module.hub.ssh_user}@${local.dns_hub}' -i ${module.key_pair.private_key_file_path} ${val.ssh_user}@${val.private_ip}", null)
}
}
}
Expand All @@ -21,13 +21,13 @@ output "dsf_hub" {
jsonar_uid = try(module.hub.jsonar_uid, null)
display_name = try(module.hub.display_name, null)
role_arn = try(module.hub.iam_role, null)
ssh_command = try("ssh -i ${module.key_pair.private_key_file_path} ${module.hub.ssh_user}@${module.hub.public_dns}", null)
ssh_command = try("ssh -i ${module.key_pair.private_key_file_path} ${module.hub.ssh_user}@${local.dns_hub}", null)
}
}

output "web_console_dsf_hub" {
value = {
public_url = try(join("", ["https://", module.hub.public_dns, ":8443/"]), null)
public_url = try(join("", ["https://", local.dns_hub, ":8443/"]), null)
private_url = try(join("", ["https://", module.hub.private_dns, ":8443/"]), null)
admin_password = nonsensitive(local.password)
}
Expand Down Expand Up @@ -69,4 +69,16 @@ output "generated_network" {
output "tokens" {
value = module.hub.access_tokens
sensitive = true
}
}

output "dns_records" {
description = "DNS CNAME records for all public-facing instances. Shows records that need to exist for zScaler access."
value = local.dns_enabled ? {
for suffix, target in local.dns_record_targets :
"${local.deployment_name_salted}-${suffix}.${var.dns_zone_domain}" => {
type = "CNAME"
target = target
auto_created = local.dns_auto_create
}
} : {}
}
Loading
Loading