-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathipranges.tf
190 lines (165 loc) · 6.14 KB
/
ipranges.tf
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# maintain AWS security groups that allow ingress from selected cloud services
# these are updated automatically by scraping the published IP ranges from each service
# note: duplicated under game/aws/terraform/modules/ipranges/ and battlehouse-infra/terraform/modules/ipranges/
# AWS SECURITY GROUP USAGE
# Security groups can have up to 50 rules (with separate total counts for IPv4 and IPv6).
# EC2 instances and network interfaces can be a member of up to 5 security groups.
# We are already hitting this limit for production game servers, which have
# frontend_ingress + backend + cloudfront_ingress (x2) + ssh_access
# If CloudFront/CloudFlare keep adding more IP ranges such that this overflows,
# then the next step might be to force all CloudFront traffic to go via the HAproxy frontend.
# CLOUDFLARE
# CloudFlare publishes their IP lists as raw data
data "http" "cloudflare_ipv4" {
url = "https://www.cloudflare.com/ips-v4"
}
data "http" "cloudflare_ipv6" {
url = "https://www.cloudflare.com/ips-v6"
}
# IP ranges, broken into lists of <= 25 elements.
# We put both an HTTP and HTTPS rule for each IP range into the same security group.
locals {
cloudflare_ipv4_chunked = chunklist(split("\n", trimspace(data.http.cloudflare_ipv4.body)), 25)
cloudflare_ipv6_chunked = chunklist(split("\n", trimspace(data.http.cloudflare_ipv6.body)), 25)
}
resource "aws_security_group" "cloudflare_ingress_chunked" {
count = max(
length(local.cloudflare_ipv4_chunked),
length(local.cloudflare_ipv6_chunked),
)
name = "${var.sitename}-cloudflare-ingress-chunked-${count.index}"
description = "Allow ingress from CloudFlare IPs"
vpc_id = var.vpc_id
tags = {
Name = "${var.sitename}-cloudflare-ingress-chunked-${count.index}"
Terraform = "true"
}
}
resource "aws_security_group_rule" "cloudflare_ingress_chunked_egress" {
# Allow egress to anywhere. Apply this rule to all chunks.
count = max(
length(local.cloudflare_ipv4_chunked),
length(local.cloudflare_ipv6_chunked),
)
type = "egress"
to_port = 0
from_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.cloudflare_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudflare_to_http_ipv4_chunked" {
count = length(local.cloudflare_ipv4_chunked)
type = "ingress"
to_port = 80
from_port = 80
protocol = "tcp"
cidr_blocks = local.cloudflare_ipv4_chunked[count.index]
security_group_id = aws_security_group.cloudflare_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudflare_to_https_ipv4_chunked" {
count = length(local.cloudflare_ipv4_chunked)
type = "ingress"
to_port = 443
from_port = 443
protocol = "tcp"
cidr_blocks = local.cloudflare_ipv4_chunked[count.index]
security_group_id = aws_security_group.cloudflare_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudflare_to_http_ipv6_chunked" {
count = length(local.cloudflare_ipv6_chunked)
type = "ingress"
to_port = 80
from_port = 80
protocol = "tcp"
ipv6_cidr_blocks = local.cloudflare_ipv6_chunked[count.index]
security_group_id = aws_security_group.cloudflare_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudflare_to_https_ipv6_chunked" {
count = length(local.cloudflare_ipv6_chunked)
type = "ingress"
to_port = 443
from_port = 443
protocol = "tcp"
ipv6_cidr_blocks = local.cloudflare_ipv6_chunked[count.index]
security_group_id = aws_security_group.cloudflare_ingress_chunked[count.index].id
}
# AMAZON CLOUDFRONT
# AWS publishes their IP lists as JSON, so we use a script to parse this
data "external" "cloudfront_ipv4" {
program = ["python", "${path.module}/get-aws-ip-ranges.py"]
query = {
protocol = "IPv4"
service = "CLOUDFRONT"
}
}
data "external" "cloudfront_ipv6" {
program = ["python", "${path.module}/get-aws-ip-ranges.py"]
query = {
protocol = "IPv6"
service = "CLOUDFRONT"
}
}
# IP ranges, broken into lists of <= 50 elements
# Note: right now we only add rules for HTTP on port 80.
# If we also want rules for HTTPS on port 443, then we'd need to break into smaller lists, or use more chunks.
locals {
cloudfront_ipv4_chunked = chunklist(
split(
",",
data.external.cloudfront_ipv4.result["prefix_list_comma_separated"],
),
50,
)
cloudfront_ipv6_chunked = chunklist(
split(
",",
data.external.cloudfront_ipv6.result["prefix_list_comma_separated"],
),
50,
)
}
resource "aws_security_group" "cloudfront_ingress_chunked" {
count = max(
length(local.cloudfront_ipv4_chunked),
length(local.cloudfront_ipv6_chunked),
)
name = "${var.sitename}-cloudfront-ingress-chunked-${count.index}"
description = "Allow ingress from Amazon CloudFront IPs (non-HTTPS)"
vpc_id = var.vpc_id
tags = {
Name = "${var.sitename}-cloudfront-ingress-chunked-${count.index}"
Terraform = "true"
}
}
resource "aws_security_group_rule" "cloudfront_ingress_chunked_egress" {
# Allow egress to anywhere. Apply this rule to all chunks.
count = max(
length(local.cloudfront_ipv4_chunked),
length(local.cloudfront_ipv6_chunked),
)
type = "egress"
to_port = 0
from_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.cloudfront_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudfront_to_http_ipv4_chunked" {
count = length(local.cloudfront_ipv4_chunked)
type = "ingress"
to_port = 80
from_port = 80
protocol = "tcp"
cidr_blocks = local.cloudfront_ipv4_chunked[count.index]
security_group_id = aws_security_group.cloudfront_ingress_chunked[count.index].id
}
resource "aws_security_group_rule" "cloudfront_to_http_ipv6_chunked" {
count = length(local.cloudfront_ipv6_chunked)
type = "ingress"
to_port = 80
from_port = 80
protocol = "tcp"
ipv6_cidr_blocks = local.cloudfront_ipv6_chunked[count.index]
security_group_id = aws_security_group.cloudfront_ingress_chunked[count.index].id
}