1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# VPC Endpoint =================================================================
# Security Group ---------------------------------------------------------------
# Created only when Interface endpoints are defined.
# Owned by this module rather than passed in, matching how the vpc module
# owns its own IAM role/policy for flow logs rather than accepting one externally.
resource "aws_security_group" "interface_endpoints" {
for_each = length(local.interface_endpoints) > 0 ? { sg = true } : {}
name = "${var.name_prefix}-${local.region_abbr}-vpce-sg"
description = "Allow HTTPS from VPC CIDR to interface VPC endpoints"
vpc_id = var.vpc_id
tags = merge(var.tags, local.module_tags, {
Name = "${var.name_prefix}-${local.region_abbr}-vpce-sg"
resource-type = "security-group"
})
lifecycle {
precondition {
condition = length("${var.name_prefix}-${local.region_abbr}-vpce-sg") <= 255
error_message = "Assembled security group name exceeds AWS's 255-character limit"
}
}
}
resource "aws_vpc_security_group_ingress_rule" "interface_endpoints_https" {
for_each = length(local.interface_endpoints) > 0 ? { sg = true } : {}
security_group_id = aws_security_group.interface_endpoints["sg"].id
description = "HTTPS from VPC CIDR"
cidr_ipv4 = var.vpc_cidr_block
from_port = 443
to_port = 443
ip_protocol = "tcp"
tags = merge(var.tags, local.module_tags, {
Name = "${var.name_prefix}-${local.region_abbr}-vpce-sg-ingress-https"
resource-type = "security-group-rule"
})
}
resource "aws_vpc_security_group_egress_rule" "interface_endpoints_all" {
for_each = length(local.interface_endpoints) > 0 ? { sg = true } : {}
security_group_id = aws_security_group.interface_endpoints["sg"].id
description = "All outbound"
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
tags = merge(var.tags, local.module_tags, {
Name = "${var.name_prefix}-${local.region_abbr}-vpce-sg-egress-all"
resource-type = "security-group-rule"
})
}
# Gateway Endpoints ------------------------------------------------------------
# Route-table-based, no ENI, no cost. S3 and DynamoDB are the only AWS
# services that currently support the Gateway type.
resource "aws_vpc_endpoint" "gateway" {
for_each = local.gateway_endpoints
vpc_id = var.vpc_id
service_name = "com.amazonaws.${var.aws_region}.${each.value.service_name}"
vpc_endpoint_type = "Gateway"
route_table_ids = var.route_table_ids
policy = each.value.policy
tags = merge(var.tags, local.module_tags, {
Name = "${var.name_prefix}-${local.region_abbr}-vpce-${each.key}"
resource-type = "vpc-endpoint"
})
}
# Interface Endpoints ----------------------------------------------------------
# ENI-based, placed in the given subnets, DNS-resolved in-VPC when enabled.
resource "aws_vpc_endpoint" "interface" {
for_each = local.interface_endpoints
vpc_id = var.vpc_id
service_name = "com.amazonaws.${var.aws_region}.${each.value.service_name}"
vpc_endpoint_type = "Interface"
subnet_ids = var.subnet_ids
security_group_ids = [aws_security_group.interface_endpoints["sg"].id]
private_dns_enabled = each.value.private_dns_enabled
policy = each.value.policy
tags = merge(var.tags, local.module_tags, {
Name = "${var.name_prefix}-${local.region_abbr}-vpce-${each.key}"
resource-type = "vpc-endpoint"
})
}
|