1
+ # Website Cloud Run service
1
2
resource "google_cloud_run_v2_service" "website" {
2
3
project = var. project_id
3
4
name = " osv-website"
@@ -32,4 +33,183 @@ resource "google_cloud_run_service_iam_binding" "website" {
32
33
]
33
34
}
34
35
35
- # TODO: Set up Google Cloud Load Balancing + Network Endpoint Group (NEG)
36
+ # SSL Certificates
37
+ resource "google_certificate_manager_dns_authorization" "website" {
38
+ project = var. project_id
39
+ name = " website-dnsauth"
40
+ description = " The dns auth for the osv.dev website"
41
+ domain = var. website_domain
42
+ }
43
+
44
+ resource "google_certificate_manager_certificate" "website" {
45
+ project = var. project_id
46
+ name = " website-cert"
47
+ description = " The osv.dev website cert"
48
+ managed {
49
+ domains = [var . website_domain , " *.${ var . website_domain } " ]
50
+ dns_authorizations = [
51
+ google_certificate_manager_dns_authorization . website . id
52
+ ]
53
+ }
54
+ lifecycle {
55
+ replace_triggered_by = [google_certificate_manager_dns_authorization . website . id ]
56
+ }
57
+ }
58
+
59
+ resource "google_certificate_manager_certificate_map" "website" {
60
+ project = var. project_id
61
+ name = " website-certmap"
62
+ description = " osv.dev website certificate map"
63
+ }
64
+
65
+ resource "google_certificate_manager_certificate_map_entry" "website" {
66
+ project = var. project_id
67
+ name = " website-certmap-entry"
68
+ description = " osv.dev website certificate map entry"
69
+ map = google_certificate_manager_certificate_map. website . name
70
+ certificates = [google_certificate_manager_certificate . website . id ]
71
+ hostname = var. website_domain
72
+
73
+ lifecycle {
74
+ replace_triggered_by = [google_certificate_manager_certificate_map . website . id , google_certificate_manager_certificate . website . id ]
75
+ }
76
+ }
77
+
78
+ # Load Balancer
79
+ module "gclb" {
80
+ source = " terraform-google-modules/lb-http/google//modules/serverless_negs"
81
+ version = " ~> 10.0"
82
+
83
+ name = " website"
84
+ project = var. project_id
85
+
86
+ enable_ipv6 = true
87
+ create_ipv6_address = true
88
+ ssl = true
89
+ certificate_map = google_certificate_manager_certificate_map. website . id
90
+
91
+ load_balancing_scheme = " EXTERNAL_MANAGED"
92
+
93
+ create_url_map = false
94
+ url_map = google_compute_url_map. website . id
95
+
96
+ backends = {
97
+ appengine = {
98
+ groups = [
99
+ {
100
+ group = google_compute_region_network_endpoint_group.appengine_neg.id
101
+ }
102
+ ]
103
+ protocol = " HTTPS"
104
+ enable_cdn = true
105
+ cdn_policy = {
106
+ cache_key_policy = {
107
+ include_host = true
108
+ include_protocol = true
109
+ include_query_string = true
110
+ }
111
+ signed_url_cache_max_age_sec = 0
112
+ }
113
+
114
+ iap_config = {
115
+ enable = false
116
+ }
117
+ log_config = {
118
+ enable = false
119
+ }
120
+ }
121
+
122
+ cloudrun = {
123
+ groups = [
124
+ {
125
+ group = google_compute_region_network_endpoint_group.website_neg.id
126
+ }
127
+ ]
128
+ protocol = " HTTPS"
129
+ enable_cdn = true
130
+ cdn_policy = {
131
+ cache_key_policy = {
132
+ include_host = true
133
+ include_protocol = true
134
+ include_query_string = true
135
+ }
136
+ signed_url_cache_max_age_sec = 0
137
+ }
138
+ connection_draining_timeout_sec = 1
139
+
140
+ iap_config = {
141
+ enable = false
142
+ }
143
+ log_config = {
144
+ enable = false
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ resource "google_compute_region_network_endpoint_group" "website_neg" {
151
+ project = var. project_id
152
+ name = " website-neg"
153
+ network_endpoint_type = " SERVERLESS"
154
+ region = google_cloud_run_v2_service. website . location
155
+ cloud_run {
156
+ service = google_cloud_run_v2_service. website . name
157
+ }
158
+ }
159
+
160
+ resource "google_compute_region_network_endpoint_group" "appengine_neg" {
161
+ project = var. project_id
162
+ name = " appengine-neg"
163
+ network_endpoint_type = " SERVERLESS"
164
+ region = google_app_engine_application. app . location_id
165
+ app_engine {}
166
+ }
167
+
168
+ resource "google_compute_url_map" "website" {
169
+ project = var. project_id
170
+ name = " website-url-map"
171
+ default_service = module. gclb . backend_services . appengine . id
172
+
173
+ host_rule {
174
+ hosts = [" *" ]
175
+ path_matcher = " allpaths"
176
+ }
177
+
178
+ path_matcher {
179
+ name = " allpaths"
180
+ default_service = module. gclb . backend_services . appengine . id
181
+ route_rules {
182
+ priority = 1
183
+ match_rules {
184
+ prefix_match = " /"
185
+ }
186
+ route_action {
187
+ # TODO(michaelkedar): adjust weights, then remove appengine fully migrated
188
+ weighted_backend_services {
189
+ backend_service = module. gclb . backend_services . appengine . id
190
+ weight = 100
191
+ }
192
+ weighted_backend_services {
193
+ backend_service = module. gclb . backend_services . cloudrun . id
194
+ weight = 0
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ # Output all the DNS records required for the website in one place.
202
+ output "website_dns_records" {
203
+ description = " DNS records that need to be created for the osv.dev website"
204
+ value = concat ([
205
+ {
206
+ data = module.gclb.external_ip
207
+ name = " ${ var . website_domain } ."
208
+ type = " A"
209
+ },
210
+ {
211
+ data = module.gclb.external_ipv6_address
212
+ name = " ${ var . website_domain } ."
213
+ type = " AAAA"
214
+ }], google_certificate_manager_dns_authorization. website . dns_resource_record )
215
+ }
0 commit comments