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
68 changes: 37 additions & 31 deletions modules/vpc-endpoint-consumer/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,34 @@ locals {
# Cluster name for tagging (use provided cluster_name or default)
cluster_name_for_tags = var.cluster_name != null ? var.cluster_name : "mpc-cluster"

# Use the VPC endpoint service names provided by partners
# Note: vpc_endpoint_service_name must be provided directly by the partner
# as AWS auto-generates these names when creating VPC endpoint services
vpc_endpoint_service_names = [
for service in var.party_services : service.vpc_endpoint_service_name
]
# Convert party_services list to map for for_each usage
party_services_map = {
for service in var.party_services : service.party_id => service
}

# Create separate map for services that need Kubernetes services
kube_services_map = {
for service in var.party_services : service.party_id => service
if service.create_kube_service
}

}

# ************************************************************
# VPC interface endpoints to connect to partner MPC services
# ************************************************************
resource "aws_vpc_endpoint" "party_interface_endpoints" {
count = length(var.party_services)
for_each = local.party_services_map

vpc_id = local.vpc_id
service_name = local.vpc_endpoint_service_names[count.index]
service_name = each.value.vpc_endpoint_service_name
vpc_endpoint_type = "Interface"
subnet_ids = length(coalesce(var.party_services[count.index].availability_zones, [])) > 0 && var.cluster_name != null ? [
subnet_ids = length(coalesce(each.value.availability_zones, [])) > 0 && var.cluster_name != null ? [
for subnet_id, subnet in data.aws_subnet.cluster_subnets : subnet_id
if subnet.map_public_ip_on_launch == false && contains(var.party_services[count.index].availability_zones, subnet.availability_zone)
if subnet.map_public_ip_on_launch == false && contains(each.value.availability_zones, subnet.availability_zone_id)
] : local.subnet_ids
security_group_ids = local.security_group_ids
service_region = var.party_services[count.index].region
service_region = each.value.region

# DNS options
private_dns_enabled = var.private_dns_enabled
Expand All @@ -61,14 +65,15 @@ resource "aws_vpc_endpoint" "party_interface_endpoints" {
tags = merge(
var.tags,
{
Name = "${var.name_prefix}-${var.party_services[count.index].name}-interface"
"mpc:partner-service" = var.party_services[count.index].name
"mpc:partner-region" = var.party_services[count.index].region
Name = "${var.name_prefix}-${each.value.name}-interface"
"mpc:partner-service" = each.value.name
"mpc:partner-party" = each.key
"mpc:partner-region" = each.value.region
"mpc:component" = "partner-interface"
"mpc:cluster" = local.cluster_name_for_tags
},
var.party_services[count.index].account_id != null ? {
"mpc:partner-account" = var.party_services[count.index].account_id
each.value.account_id != null ? {
"mpc:partner-account" = each.value.account_id
} : {},
)

Expand All @@ -92,34 +97,35 @@ resource "kubernetes_namespace" "partner_namespace" {
# Create Kubernetes services that route to the VPC interface endpoints
# *********************************************************************
resource "kubernetes_service" "party_services" {
count = length([for service in var.party_services : service if service.create_kube_service])
for_each = local.kube_services_map

metadata {
name = "mpc-node-${var.party_services[count.index].party_id}"
name = "mpc-node-${each.key}"
namespace = var.create_namespace ? kubernetes_namespace.partner_namespace[0].metadata[0].name : var.namespace

annotations = merge({
"mpc.io/connection-type" = "partner-interface"
"mpc.io/partner-service" = var.party_services[count.index].name
"mpc.io/partner-service" = each.value.name
"mpc.io/partner-party" = each.key
},
var.party_services[count.index].account_id != null ? {
"mpc.io/partner-account" = var.party_services[count.index].account_id
each.value.account_id != null ? {
"mpc.io/partner-account" = each.value.account_id
} : {},
var.party_services[count.index].kube_service_config.additional_annotations)
each.value.kube_service_config.additional_annotations)

labels = merge({
"app.kubernetes.io/name" = "kms-${var.party_services[count.index].party_id}-core"
"app.kubernetes.io/instance" = "kms-${var.party_services[count.index].party_id}-core"
"app.kubernetes.io/name" = "kms-${each.key}-core"
"app.kubernetes.io/instance" = "kms-${each.key}-core"
"app.kubernetes.io/component" = "mpc-partner-interface"
"app.kubernetes.io/part-of" = "mpc-cluster"
"mpc.io/partner-service" = "true"
}, var.party_services[count.index].kube_service_config.labels)
}, each.value.kube_service_config.labels)
}

spec {
type = "ExternalName"
external_name = aws_vpc_endpoint.party_interface_endpoints[count.index].dns_entry[0].dns_name
session_affinity = var.party_services[count.index].kube_service_config.session_affinity
external_name = aws_vpc_endpoint.party_interface_endpoints[each.key].dns_entry[0].dns_name
session_affinity = each.value.kube_service_config.session_affinity

dynamic "port" {
for_each = concat(
Expand All @@ -143,15 +149,15 @@ resource "kubernetes_service" "party_services" {
# Create Route53 private hosted zone records for custom DNS names (in progress,optional)
# **************************************************************************************
resource "aws_route53_record" "partner_dns" {
count = var.create_custom_dns_records ? length(var.party_services) : 0
for_each = var.create_custom_dns_records ? local.party_services_map : {}

zone_id = var.private_zone_id
name = "${var.party_services[count.index].name}.${var.dns_domain}"
name = "${each.value.name}.${var.dns_domain}"
type = "A"

alias {
name = aws_vpc_endpoint.party_interface_endpoints[count.index].dns_entry[0].dns_name
zone_id = aws_vpc_endpoint.party_interface_endpoints[count.index].dns_entry[0].hosted_zone_id
name = aws_vpc_endpoint.party_interface_endpoints[each.key].dns_entry[0].dns_name
zone_id = aws_vpc_endpoint.party_interface_endpoints[each.key].dns_entry[0].hosted_zone_id
evaluate_target_health = true
}
}
46 changes: 24 additions & 22 deletions modules/vpc-endpoint-consumer/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,60 +1,61 @@
output "vpc_interface_endpoint_ids" {
description = "IDs of the created VPC interface endpoints"
value = [for endpoint in aws_vpc_endpoint.party_interface_endpoints : endpoint.id]
value = [for endpoint in values(aws_vpc_endpoint.party_interface_endpoints) : endpoint.id]
}

output "vpc_interface_endpoint_dns_names" {
description = "DNS names of the created VPC interface endpoints"
value = [for endpoint in aws_vpc_endpoint.party_interface_endpoints : endpoint.dns_entry[0].dns_name]
value = [for endpoint in values(aws_vpc_endpoint.party_interface_endpoints) : endpoint.dns_entry[0].dns_name]
}

output "vpc_interface_endpoint_hosted_zone_ids" {
description = "Hosted zone IDs of the created VPC interface endpoints"
value = [for endpoint in aws_vpc_endpoint.party_interface_endpoints : endpoint.dns_entry[0].hosted_zone_id]
value = [for endpoint in values(aws_vpc_endpoint.party_interface_endpoints) : endpoint.dns_entry[0].hosted_zone_id]
}

output "vpc_interface_endpoint_service_names" {
description = "Service names of the created VPC interface endpoints"
value = [for endpoint in aws_vpc_endpoint.party_interface_endpoints : endpoint.service_name]
value = [for endpoint in values(aws_vpc_endpoint.party_interface_endpoints) : endpoint.service_name]
}

output "partner_service_details" {
description = "Detailed information about the partner services and their connections"
value = [
for i, endpoint in aws_vpc_endpoint.party_interface_endpoints : {
service_name = var.party_services[i].name
partner_region = var.party_services[i].region
partner_account_id = var.party_services[i].account_id # Can be null
for party_id, endpoint in aws_vpc_endpoint.party_interface_endpoints : {
party_id = party_id
service_name = local.party_services_map[party_id].name
partner_region = local.party_services_map[party_id].region
partner_account_id = local.party_services_map[party_id].account_id # Can be null
vpc_endpoint_service_name = endpoint.service_name
vpc_interface_endpoint_id = endpoint.id
vpc_interface_dns_name = endpoint.dns_entry[0].dns_name
vpc_interface_hosted_zone_id = endpoint.dns_entry[0].hosted_zone_id
network_interface_ids = endpoint.network_interface_ids
state = endpoint.state
created_kube_service = var.party_services[i].create_kube_service
ports = var.party_services[i].ports
created_kube_service = local.party_services_map[party_id].create_kube_service
ports = local.party_services_map[party_id].ports
}
]
}

output "kubernetes_service_names" {
description = "Names of the created Kubernetes services for partner connections"
value = [
for i, service in kubernetes_service.party_services : service.metadata[0].name
for service in values(kubernetes_service.party_services) : service.metadata[0].name
]
}

output "kubernetes_service_namespaces" {
description = "Namespaces of the created Kubernetes services for partner connections"
value = [
for service in kubernetes_service.party_services : service.metadata[0].namespace
for service in values(kubernetes_service.party_services) : service.metadata[0].namespace
]
}

output "kubernetes_service_external_names" {
description = "External names (VPC interface endpoint DNS) used by the Kubernetes services"
value = [
for service in kubernetes_service.party_services : service.spec[0].external_name
for service in values(kubernetes_service.party_services) : service.spec[0].external_name
]
}

Expand All @@ -66,7 +67,7 @@ output "namespace_name" {
output "custom_dns_records" {
description = "Custom DNS records created for the VPC interface endpoints (if enabled)"
value = var.create_custom_dns_records ? [
for i, record in aws_route53_record.partner_dns : {
for record in values(aws_route53_record.partner_dns) : {
name = record.name
type = record.type
zone_id = record.zone_id
Expand All @@ -81,9 +82,9 @@ output "connection_summary" {
total_partners = length(var.party_services)
partner_regions = distinct([for service in var.party_services : service.region])
partner_accounts = distinct(compact([for service in var.party_services : service.account_id]))
vpc_interface_endpoints = length(aws_vpc_endpoint.party_interface_endpoints)
kubernetes_services = length(kubernetes_service.party_services)
custom_dns_records = var.create_custom_dns_records ? length(aws_route53_record.partner_dns) : 0
vpc_interface_endpoints = length(values(aws_vpc_endpoint.party_interface_endpoints))
kubernetes_services = length(values(kubernetes_service.party_services))
custom_dns_records = var.create_custom_dns_records ? length(values(aws_route53_record.partner_dns)) : 0
namespace = var.create_namespace && anytrue([for service in var.party_services : service.create_kube_service]) ? kubernetes_namespace.partner_namespace[0].metadata[0].name : var.namespace
}
}
Expand All @@ -92,21 +93,22 @@ output "connection_summary" {
output "partner_connection_endpoints" {
description = "Connection endpoints for applications to use when connecting to partner services"
value = {
for i, service in var.party_services : service.name => {
for party_id, service in local.party_services_map : party_id => {
# Primary connection methods
vpc_interface_dns = aws_vpc_endpoint.party_interface_endpoints[i].dns_entry[0].dns_name
kubernetes_service_name = service.create_kube_service ? "${service.name}.${var.create_namespace && anytrue([for s in var.party_services : s.create_kube_service]) ? kubernetes_namespace.partner_namespace[0].metadata[0].name : var.namespace}.svc.cluster.local" : null
custom_dns_name = var.create_custom_dns_records ? "${service.name}.${var.dns_domain}" : null
vpc_interface_dns = aws_vpc_endpoint.party_interface_endpoints[party_id].dns_entry[0].dns_name
kubernetes_service_name = service.create_kube_service ? "mpc-node-${party_id}.${var.create_namespace && anytrue([for s in var.party_services : s.create_kube_service]) ? kubernetes_namespace.partner_namespace[0].metadata[0].name : var.namespace}.svc.cluster.local" : null
custom_dns_name = var.create_custom_dns_records ? "party-${party_id}.${var.dns_domain}" : null

# Service details
service_name = service.name
ports = service.ports
partner_region = service.region
partner_account = service.account_id # Can be null if not provided
partner_name = service.partner_name # Can be null if not provided
connection_type = "vpc-interface"

# Advanced connection options
network_interface_ips = aws_vpc_endpoint.party_interface_endpoints[i].network_interface_ids
network_interface_ips = aws_vpc_endpoint.party_interface_endpoints[party_id].network_interface_ids
}
}
}
2 changes: 1 addition & 1 deletion modules/vpc-endpoint-provider/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ data "aws_subnet" "nlb_subnet" {

# Get all availability zones from the NLB subnets
locals {
availability_zones = [for subnet in data.aws_subnet.nlb_subnet : subnet.availability_zone]
availability_zones = [for subnet in data.aws_subnet.nlb_subnet : subnet.availability_zone_id]
}

# **************************************************************
Expand Down