Skip to content

Commit e2b77ed

Browse files
authored
feat: Add project for backend service and health check for cross project reference (terraform-google-modules#345)
1 parent ddddf32 commit e2b77ed

File tree

29 files changed

+672
-17
lines changed

29 files changed

+672
-17
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ module "gce-lb-http" {
120120
| Name | Description | Type | Default | Required |
121121
|------|-------------|------|---------|:--------:|
122122
| address | Existing IPv4 address to use (the actual IP address value) | `string` | `null` | no |
123-
| backends | Map backend indices to list of backend maps. | <pre>map(object({<br> port = optional(number)<br> protocol = optional(string)<br> port_name = optional(string)<br> description = optional(string)<br> enable_cdn = optional(bool)<br> compression_mode = optional(string)<br> security_policy = optional(string, null)<br> edge_security_policy = optional(string, null)<br> custom_request_headers = optional(list(string))<br> custom_response_headers = optional(list(string))<br><br> timeout_sec = optional(number)<br> connection_draining_timeout_sec = optional(number)<br> session_affinity = optional(string)<br> affinity_cookie_ttl_sec = optional(number)<br><br> health_check = object({<br> host = optional(string)<br> request_path = optional(string)<br> request = optional(string)<br> response = optional(string)<br> port = optional(number)<br> port_name = optional(string)<br> proxy_header = optional(string)<br> port_specification = optional(string)<br> check_interval_sec = optional(number)<br> timeout_sec = optional(number)<br> healthy_threshold = optional(number)<br> unhealthy_threshold = optional(number)<br> logging = optional(bool)<br> })<br><br> log_config = object({<br> enable = optional(bool)<br> sample_rate = optional(number)<br> })<br><br> groups = list(object({<br> group = string<br><br> balancing_mode = optional(string)<br> capacity_scaler = optional(number)<br> description = optional(string)<br> max_connections = optional(number)<br> max_connections_per_instance = optional(number)<br> max_connections_per_endpoint = optional(number)<br> max_rate = optional(number)<br> max_rate_per_instance = optional(number)<br> max_rate_per_endpoint = optional(number)<br> max_utilization = optional(number)<br> }))<br> iap_config = object({<br> enable = bool<br> oauth2_client_id = optional(string)<br> oauth2_client_secret = optional(string)<br> })<br> cdn_policy = optional(object({<br> cache_mode = optional(string)<br> signed_url_cache_max_age_sec = optional(string)<br> default_ttl = optional(number)<br> max_ttl = optional(number)<br> client_ttl = optional(number)<br> negative_caching = optional(bool)<br> negative_caching_policy = optional(object({<br> code = optional(number)<br> ttl = optional(number)<br> }))<br> serve_while_stale = optional(number)<br> cache_key_policy = optional(object({<br> include_host = optional(bool)<br> include_protocol = optional(bool)<br> include_query_string = optional(bool)<br> query_string_blacklist = optional(list(string))<br> query_string_whitelist = optional(list(string))<br> include_http_headers = optional(list(string))<br> include_named_cookies = optional(list(string))<br> }))<br> }))<br> }))</pre> | n/a | yes |
123+
| backends | Map backend indices to list of backend maps. | <pre>map(object({<br> port = optional(number)<br> project = optional(string)<br> protocol = optional(string)<br> port_name = optional(string)<br> description = optional(string)<br> enable_cdn = optional(bool)<br> compression_mode = optional(string)<br> security_policy = optional(string, null)<br> edge_security_policy = optional(string, null)<br> custom_request_headers = optional(list(string))<br> custom_response_headers = optional(list(string))<br><br> timeout_sec = optional(number)<br> connection_draining_timeout_sec = optional(number)<br> session_affinity = optional(string)<br> affinity_cookie_ttl_sec = optional(number)<br><br> health_check = object({<br> host = optional(string)<br> request_path = optional(string)<br> request = optional(string)<br> response = optional(string)<br> port = optional(number)<br> port_name = optional(string)<br> proxy_header = optional(string)<br> port_specification = optional(string)<br> check_interval_sec = optional(number)<br> timeout_sec = optional(number)<br> healthy_threshold = optional(number)<br> unhealthy_threshold = optional(number)<br> logging = optional(bool)<br> })<br><br> log_config = object({<br> enable = optional(bool)<br> sample_rate = optional(number)<br> })<br><br> groups = list(object({<br> group = string<br><br> balancing_mode = optional(string)<br> capacity_scaler = optional(number)<br> description = optional(string)<br> max_connections = optional(number)<br> max_connections_per_instance = optional(number)<br> max_connections_per_endpoint = optional(number)<br> max_rate = optional(number)<br> max_rate_per_instance = optional(number)<br> max_rate_per_endpoint = optional(number)<br> max_utilization = optional(number)<br> }))<br> iap_config = object({<br> enable = bool<br> oauth2_client_id = optional(string)<br> oauth2_client_secret = optional(string)<br> })<br> cdn_policy = optional(object({<br> cache_mode = optional(string)<br> signed_url_cache_max_age_sec = optional(string)<br> default_ttl = optional(number)<br> max_ttl = optional(number)<br> client_ttl = optional(number)<br> negative_caching = optional(bool)<br> negative_caching_policy = optional(object({<br> code = optional(number)<br> ttl = optional(number)<br> }))<br> serve_while_stale = optional(number)<br> cache_key_policy = optional(object({<br> include_host = optional(bool)<br> include_protocol = optional(bool)<br> include_query_string = optional(bool)<br> query_string_blacklist = optional(list(string))<br> query_string_whitelist = optional(list(string))<br> include_http_headers = optional(list(string))<br> include_named_cookies = optional(list(string))<br> }))<br> }))<br> }))</pre> | n/a | yes |
124124
| certificate | Content of the SSL certificate. Required if `ssl` is `true` and `ssl_certificates` is empty. | `string` | `null` | no |
125125
| certificate\_map | Certificate Map ID in format projects/{project}/locations/global/certificateMaps/{name}. Identifies a certificate map associated with the given target proxy | `string` | `null` | no |
126126
| create\_address | Create a new global IPv4 address | `bool` | `true` | no |

autogen/main.tf.tmpl

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ locals {
2323
create_http_forward = var.http_forward || var.https_redirect
2424

2525
{% if not serverless %}{# Serverless NEGs don't support health checks #}
26-
health_checked_backends = { for backend_index, backend_value in var.backends : backend_index => backend_value if backend_value["health_check"] != null }
26+
health_checked_backends = { for backend_index, backend_value in var.backends : backend_index => backend_value if backend_value["health_check"] != null }
2727
{% endif %}
2828

2929
is_internal = var.load_balancing_scheme == "INTERNAL_SELF_MANAGED"
@@ -163,6 +163,7 @@ resource "google_compute_managed_ssl_certificate" "default" {
163163
}
164164

165165
resource "google_compute_url_map" "default" {
166+
provider = google-beta
166167
project = var.project
167168
count = var.create_url_map ? 1 : 0
168169
name = "${var.name}-url-map"
@@ -184,7 +185,7 @@ resource "google_compute_backend_service" "default" {
184185
provider = google-beta
185186
for_each = var.backends
186187

187-
project = var.project
188+
project = coalesce(each.value["project"], var.project)
188189
name = "${var.name}-backend-${each.key}"
189190

190191
load_balancing_scheme = var.load_balancing_scheme
@@ -302,7 +303,7 @@ resource "google_compute_backend_service" "default" {
302303
resource "google_compute_health_check" "default" {
303304
provider = google-beta
304305
for_each = local.health_checked_backends
305-
project = var.project
306+
project = coalesce(each.value["project"], var.project)
306307
name = "${var.name}-hc-${each.key}"
307308

308309
check_interval_sec = lookup(each.value["health_check"], "check_interval_sec", 5)

autogen/variables.tf.tmpl

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ variable "backends" {
8787
{% if not serverless %}{# not necessary for serverless as default port_name=http, protocol=HTTP #}
8888
port = optional(number)
8989
{% endif %}
90+
project = optional(string)
9091
protocol = optional(string)
9192
port_name = optional(string)
9293
description = optional(string)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# HTTP Load Balancer Example
2+
3+
[![button](http://gstatic.com/cloudssh/images/open-btn.png)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/terraform-google-lb-http&working_dir=examples/cross-project-mig-backend&page=shell&tutorial=README.md)
4+
5+
This example creates a global HTTP forwarding rule in host project to forward traffic to instance groups in service project.
6+
7+
## Change to the example directory
8+
9+
```
10+
[[ `basename $PWD` != cross-project-mig-backend ]] && cd examples/cross-project-mig-backend
11+
```
12+
13+
## Install Terraform
14+
15+
1. Install Terraform if it is not already installed (visit [terraform.io](https://terraform.io) for other distributions):
16+
17+
## Set up the environment
18+
19+
20+
1. Configure the environment for Terraform:
21+
22+
```
23+
[[ $CLOUD_SHELL ]] || gcloud auth application-default login
24+
```
25+
26+
## Run Terraform
27+
28+
```
29+
terraform init
30+
terraform apply
31+
```
32+
33+
## Test load balancing
34+
35+
1. Open the URL of the load balancer in your browser:
36+
37+
```
38+
echo http://$(terraform output load-balancer-ip)
39+
```
40+
41+
## Cleanup
42+
43+
1. Remove all resources created by terraform:
44+
45+
```
46+
terraform destroy
47+
```
48+
49+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
50+
## Inputs
51+
52+
| Name | Description | Type | Default | Required |
53+
|------|-------------|------|---------|:--------:|
54+
| host\_project | ID for the Shared VPC host project | `any` | n/a | yes |
55+
| network\_name | n/a | `string` | `"multi-mig-cross-project-mig"` | no |
56+
| region | n/a | `string` | `"us-central1"` | no |
57+
| service\_project | ID for the Shared VPC service project where instances will be deployed | `any` | n/a | yes |
58+
59+
## Outputs
60+
61+
| Name | Description |
62+
|------|-------------|
63+
| load-balancer-ip | The external IP assigned to the load balancer. |
64+
65+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash -xe
2+
3+
RPM_INSTALL_ARGS="install -y httpd php php-common"
4+
5+
if [ -f "/etc/redhat-release" ]; then
6+
yum update -y || dnf update -y
7+
yum $RPM_INSTALL_ARGS || dnf $RPM_INSTALL_ARGS
8+
else
9+
apt-get update
10+
apt-get install -y apache2 libapache2-mod-php
11+
fi
12+
13+
cat > /var/www/html/index.php <<'EOF'
14+
<?php
15+
function metadata_value($value) {
16+
$opts = array(
17+
"http" => array(
18+
"method" => "GET",
19+
"header" => "Metadata-Flavor: Google"
20+
)
21+
);
22+
$context = stream_context_create($opts);
23+
$content = file_get_contents("http://metadata/computeMetadata/v1/$value", false, $context);
24+
return $content;
25+
}
26+
?>
27+
28+
<!doctype html>
29+
<html>
30+
<head>
31+
<!-- Compiled and minified CSS -->
32+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css">
33+
34+
<!-- Compiled and minified JavaScript -->
35+
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/js/materialize.min.js"></script>
36+
<title>Frontend Web Server</title>
37+
</head>
38+
<body>
39+
<div class="container">
40+
<div class="row">
41+
<div class="col s2">&nbsp;</div>
42+
<div class="col s8">
43+
44+
45+
<div class="card blue">
46+
<div class="card-content white-text">
47+
<div class="card-title">Backend that serviced this request</div>
48+
</div>
49+
<div class="card-content white">
50+
<table class="bordered">
51+
<tbody>
52+
<tr>
53+
<td>Name</td>
54+
<td><?php printf(metadata_value("instance/name")) ?></td>
55+
</tr>
56+
<tr>
57+
<td>ID</td>
58+
<td><?php printf(metadata_value("instance/id")) ?></td>
59+
</tr>
60+
<tr>
61+
<td>Hostname</td>
62+
<td><?php printf(metadata_value("instance/hostname")) ?></td>
63+
</tr>
64+
<tr>
65+
<td>Zone</td>
66+
<td><?php printf(metadata_value("instance/zone")) ?></td>
67+
</tr>
68+
<tr>
69+
<td>Machine Type</td>
70+
<td><?php printf(metadata_value("instance/machine-type")) ?></td>
71+
</tr>
72+
<tr>
73+
<td>Project</td>
74+
<td><?php printf(metadata_value("project/project-id")) ?></td>
75+
</tr>
76+
<tr>
77+
<td>Internal IP</td>
78+
<td><?php printf(metadata_value("instance/network-interfaces/0/ip")) ?></td>
79+
</tr>
80+
<tr>
81+
<td>External IP</td>
82+
<td><?php printf(metadata_value("instance/network-interfaces/0/access-configs/0/external-ip")) ?></td>
83+
</tr>
84+
</tbody>
85+
</table>
86+
</div>
87+
</div>
88+
89+
<div class="card blue">
90+
<div class="card-content white-text">
91+
<div class="card-title">Proxy that handled this request</div>
92+
</div>
93+
<div class="card-content white">
94+
<table class="bordered">
95+
<tbody>
96+
<tr>
97+
<td>Address</td>
98+
<td><?php printf($_SERVER["HTTP_HOST"]); ?></td>
99+
</tr>
100+
</tbody>
101+
</table>
102+
</div>
103+
104+
</div>
105+
</div>
106+
<div class="col s2">&nbsp;</div>
107+
</div>
108+
</div>
109+
</html>
110+
EOF
111+
112+
mv /var/www/html/index.html /var/www/html/index.html.old || echo "Old index doesn't exist"
113+
114+
[[ -n "${PROXY_PATH}" ]] && mkdir -p /var/www/html/${PROXY_PATH} && cp /var/www/html/index.php /var/www/html/${PROXY_PATH}/index.php
115+
116+
chkconfig httpd on || systemctl enable httpd || systemctl enable apache2
117+
service httpd restart || systemctl restart httpd || systemctl restart apache2
118+
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
18+
# [START cloudloadbalancing_ext_http_gce_shared_vpc]
19+
module "gce-lb-http" {
20+
source = "../../"
21+
name = "ci-crossproject-lb"
22+
project = var.host_project
23+
target_tags = ["allow-cross-project-mig"]
24+
firewall_projects = [var.host_project]
25+
firewall_networks = [var.network_name]
26+
load_balancing_scheme = "EXTERNAL_MANAGED"
27+
28+
backends = {
29+
default = {
30+
project = var.service_project
31+
protocol = "HTTP"
32+
port = 80
33+
port_name = "http"
34+
timeout_sec = 10
35+
enable_cdn = false
36+
37+
health_check = {
38+
request_path = "/"
39+
port = 80
40+
}
41+
42+
log_config = {
43+
enable = true
44+
sample_rate = 1.0
45+
}
46+
47+
groups = [
48+
{
49+
group = module.mig.instance_group
50+
}
51+
]
52+
53+
iap_config = {
54+
enable = false
55+
}
56+
}
57+
}
58+
}
59+
# [END cloudloadbalancing_ext_http_gce_shared_vpc]

0 commit comments

Comments
 (0)