Write

# ---------------------------------------------------------------------------------------------------------------------
# TERRAGRUNT CONFIGURATION
# ---------------------------------------------------------------------------------------------------------------------

terraform {
  source = "tfr://crow.infrastructure.immuta.io/internal/networking-privatelink-service-provider/aws?version=1.0.0"
}

# Include all settings from the root terragrunt.hcl file
include {
  path = find_in_parent_folders()
}

# Even though the domain is in this account, the module requires that a separate provider be supplied.
generate "provider_domain" {
  path      = "provider-domain.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider aws {
  alias   = "domain_account"
  profile = "immuta-${local.account_vars.locals.account_name}"
  region  = "${local.aws_region}"
}
EOF
}

# ---------------------------------------------------------------------------------------------------------------------
# Locals are named constants that are reusable within the configuration.
# ---------------------------------------------------------------------------------------------------------------------
locals {
  # Automatically load common variables shared across all accounts
  common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))

  # Automatically load account-level variables
  account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))

  # Automatically load region-level variables
  region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))

  # Extract the region and environment for easy access
  aws_region           = local.region_vars.locals.aws_region
  aws_region_shortname = local.region_vars.locals.aws_region_shortname
  default_region       = local.common_vars.locals.default_region
  env                  = local.account_vars.locals.env
  account_name         = local.account_vars.locals.account_name

  # A local for more convenient access to the accounts map.
  accounts   = local.common_vars.locals.accounts
  account_id = local.accounts[replace(local.account_name, "-", "_")].id

  cidr_blocks = local.common_vars.locals.cidr_blocks

  tags = merge(local.common_vars.locals.global_tags, {
    tfpath = "/platform-management/${local.aws_region}/churn-forecast-privatelink"
  })
}

# ---------------------------------------------------------------------------------------------------------------------
# MODULE DEPENDENCIES
# ---------------------------------------------------------------------------------------------------------------------

dependency cluster {
  config_path = "../eks-platform-mgmt-${local.aws_region_shortname}-1"
}

dependency r53_zone {
  config_path = "../../_global/ic-ops-net-public-dns"
}

# ---------------------------------------------------------------------------------------------------------------------
# MODULE PARAMETERS
# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
# ---------------------------------------------------------------------------------------------------------------------
inputs = {
  acceptance_required = true
  nlb_tags = [
    {
      "service.k8s.aws/stack" = "ingress-nginx-private/ingress-nginx-private-controller"
      "elbv2.k8s.aws/cluster" = dependency.cluster.outputs.cluster_name
    }
  ]
  private_dns_name = "churn-forecast.ic-ops.net"
  allowed_principals = [
    "arn:aws:iam::${local.accounts["root"].id}:root",
    "arn:aws:iam::${local.accounts["infrastructure"].id}:root",
    "arn:aws:iam::231431240278:root" //federal team
  ]
  route53_zone_id = dependency.r53_zone.outputs.zone_id

  tags = local.tags
}


The file /Users/steve.briggs/projects/customer-platform-infrastructure/platform-management/us-east-1/churn-forecast-privatelink/terragrunt.hcl has been updated successfully. (file state is current in your context — no need to Read it back)

# ---------------------------------------------------------------------------------------------------------------------
# TERRAGRUNT CONFIGURATION
# ---------------------------------------------------------------------------------------------------------------------

terraform {
  source = "tfr://crow.infrastructure.immuta.io/internal/networking-privatelink-service-provider/aws?version=1.0.0"
}

# Include all settings from the root terragrunt.hcl file
include {
  path = find_in_parent_folders()
}

# Even though the domain is in this account, the module requires that a separate provider be supplied.
generate "provider_domain" {
  path      = "provider-domain.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider aws {
  alias   = "domain_account"
  profile = "immuta-${local.account_vars.locals.account_name}"
  region  = "${local.aws_region}"
}
EOF
}

# ---------------------------------------------------------------------------------------------------------------------
# Locals are named constants that are reusable within the configuration.
# ---------------------------------------------------------------------------------------------------------------------
locals {
  # Automatically load common variables shared across all accounts
  common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))

  # Automatically load account-level variables
  account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))

  # Automatically load region-level variables
  region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))

  # Extract the region and environment for easy access
  aws_region           = local.region_vars.locals.aws_region
  aws_region_shortname = local.region_vars.locals.aws_region_shortname
  default_region       = local.common_vars.locals.default_region
  env                  = local.account_vars.locals.env
  account_name         = local.account_vars.locals.account_name

  # A local for more convenient access to the accounts map.
  accounts   = local.common_vars.locals.accounts
  account_id = local.accounts[replace(local.account_name, "-", "_")].id

  cidr_blocks = local.common_vars.locals.cidr_blocks

  tags = merge(local.common_vars.locals.global_tags, {
    tfpath = "/platform-management/${local.aws_region}/churn-forecast-privatelink"
  })
}

# ---------------------------------------------------------------------------------------------------------------------
# MODULE DEPENDENCIES
# ---------------------------------------------------------------------------------------------------------------------

dependency cluster {
  config_path = "../eks-platform-mgmt-${local.aws_region_shortname}-1"
}

dependency r53_zone {
  config_path = "../../_global/ic-ops-net-public-dns"
}

# ---------------------------------------------------------------------------------------------------------------------
# MODULE PARAMETERS
# These are the variables we have to pass in to use the module specified in the terragrunt configuration above
# ---------------------------------------------------------------------------------------------------------------------
inputs = {
  acceptance_required = true
  nlb_tags = [
    {
      "service.k8s.aws/stack" = "ingress-nginx-private/ingress-nginx-private-controller"
      "elbv2.k8s.aws/cluster" = dependency.cluster.outputs.cluster_name
    }
  ]
  private_dns_name = "churn-forecast.ic-ops.net"
  allowed_principals = [
    "arn:aws:iam::${local.accounts["root"].id}:root",
    "arn:aws:iam::${local.accounts["infrastructure"].id}:root",
    "arn:aws:iam::231431240278:root" //federal team
  ]
  route53_zone_id = dependency.r53_zone.outputs.zone_id

  tags = local.tags
}

-# Adds a Route53 record for churn-forecast.ic-ops.net pointing to the existing

-# platform-mgmt PrivateLink endpoint service (same NLB, cannot have two services).

+  source = "tfr://crow.infrastructure.immuta.io/internal/networking-privatelink-service-provider/aws?version=1.0.0"

+# Even though the domain is in this account, the module requires that a separate provider be supplied.

+  profile = "immuta-${local.account_vars.locals.account_name}"

-  aws_region   = local.region_vars.locals.aws_region

-  account_name = local.account_vars.locals.account_name

-  accounts     = local.common_vars.locals.accounts

+  # Extract the region and environment for easy access

+  aws_region           = local.region_vars.locals.aws_region

+  aws_region_shortname = local.region_vars.locals.aws_region_shortname

+  default_region       = local.common_vars.locals.default_region

+  env                  = local.account_vars.locals.env

+  account_name         = local.account_vars.locals.account_name

+  # A local for more convenient access to the accounts map.

+  accounts   = local.common_vars.locals.accounts

+  account_id = local.accounts[replace(local.account_name, "-", "_")].id

+  cidr_blocks = local.common_vars.locals.cidr_blocks

-  config_path = "../platform-mgmt-privatelink"

+  config_path = "../eks-platform-mgmt-${local.aws_region_shortname}-1"

+# These are the variables we have to pass in to use the module specified in the terragrunt configuration above

+      "service.k8s.aws/stack" = "ingress-nginx-private/ingress-nginx-private-controller"

+      "elbv2.k8s.aws/cluster" = dependency.cluster.outputs.cluster_name

+  private_dns_name = "churn-forecast.ic-ops.net"

+    "arn:aws:iam::${local.accounts["root"].id}:root",

+    "arn:aws:iam::${local.accounts["infrastructure"].id}:root",

+    "arn:aws:iam::231431240278:root" //federal team

+  route53_zone_id = dependency.r53_zone.outputs.zone_id

# ---------------------------------------------------------------------------------------------------------------------
# TERRAGRUNT CONFIGURATION
# Adds a Route53 record for churn-forecast.ic-ops.net pointing to the existing
# platform-mgmt PrivateLink endpoint service (same NLB, cannot have two services).
# ---------------------------------------------------------------------------------------------------------------------

terraform {
  source = "."
}

# Include all settings from the root terragrunt.hcl file
include {
  path = find_in_parent_folders()
}

# ---------------------------------------------------------------------------------------------------------------------
# Locals are named constants that are reusable within the configuration.
# ---------------------------------------------------------------------------------------------------------------------
locals {
  # Automatically load common variables shared across all accounts
  common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))

  # Automatically load account-level variables
  account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))

  # Automatically load region-level variables
  region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))

  aws_region   = local.region_vars.locals.aws_region
  account_name = local.account_vars.locals.account_name
  accounts     = local.common_vars.locals.accounts

  tags = merge(local.common_vars.locals.global_tags, {
    tfpath = "/platform-management/${local.aws_region}/churn-forecast-privatelink"
  })
}

# ---------------------------------------------------------------------------------------------------------------------
# MODULE DEPENDENCIES
# ---------------------------------------------------------------------------------------------------------------------

dependency platform_mgmt_privatelink {
  config_path = "../platform-mgmt-privatelink"
}

dependency r53_zone {
  config_path = "../../_global/ic-ops-net-public-dns"
}


* Failed to execute "terraform apply -target=aws_vpc_endpoint_service.privatelink_sp" in ./.terragrunt-cache/3YfAjJ8Cc7owZWuY6fyH_zom3-g/_r5HllpVx0PqABJghwzRR_heXbw   ╷   │ Error: creating EC2 VPC End…


Mount Kubernetes secret as env vars in kubectl run


Reverted. The file is back to the first version — `networking-privatelink-service-provider` module with `private_dns_name = "churn-forecast.ic-ops.net"`, matching the `platform-mgmt-privatelink` structure.


afplay ~/.claude/sounds/mario/stop/stomp.wav 2>/dev/null || true


here is some additional context, I am having trouble wrapping my head around can you help? Steve Briggs  [12:05 PM]
Trying to get networking sorted out for Mo's app;  I should just be able to replicate the mgmt privatelink setup that argocd is using?
6 repliesHaris Khan  [12:21 PM]
Yep!
Steve Briggs  [12:21 PM]
it complains that the LB is already associated with a VPCE
Haris Khan  [12:22 PM]
That's ok, we just need to point the DNS at the existing endpoint
[12:22 PM]I don't think we need to make any changes to the actual infra
[12:23 PM]@Curt correct me if I'm wrong there
[12:24 PM]That PrivateLink service is already associated with the LB of the private ingress controller on the cluster, which will route traffic based on the hostname  (edited)


OK so now it clicks, fr fr. The key insight from Haris: the PrivateLink endpoint service already fronts the nginx NLB, and nginx routes by hostname. The endpoint doesn't care which hostname is requested — it just forwards TCP to the NLB, and nginx does the routing. So `churn-forecast.ic-ops.net` traffic would work fine through the existing endpoint.

The VPN problem is pure DNS: from VPN-connected VPCs, `argocd.ic-ops.net` resolves to the **endpoint ENI IPs** (via the PrivateLink private DNS override), while `churn-forecast.ic-ops.net` resolves to the raw NLB IPs (from the public zone / external-dns record) — which aren't reachable from VPN directly.

The fix: in the `ic-ops.net` private hosted zone, add a CNAME record:

```
churn-forecast.ic-ops.net → CNAME → argocd.ic-ops.net
```

When a VPN-connected VPC resolves `churn-forecast.ic-ops.net`, it follows the CNAME to `argocd.ic-ops.net`, which then gets the private DNS override → endpoint ENI IPs → traffic flows through the existing endpoint → NLB → nginx → your app.

So the `churn-forecast-privatelink` module doesn't need the `networking-privatelink-service-provider` module at all. It just needs a single Route53 CNAME record. Want me to write that Terraform — a `main.tf` + updated `terragrunt.hcl` with `source = "."` that creates the CNAME in zone `Z0504794QPRVP19I71F6`?


here is some additional context, I am having trouble wrapping my head around can you help? Steve Briggs  [12:05 PM] Trying to get networking sorted out for Mo's app;  I should just be able to replicat…


<local-command-caveat>Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.</local-command-caveat>


<command-name>/exit</command-name>
            <command-message>exit</command-message>
            <command-args></command-args>


<local-command-stdout>Catch you later!</local-command-stdout>