Merge branch 'master' into cmalpe/kms-import-job

This commit is contained in:
cmalpe 2023-10-30 20:32:50 +05:30 committed by GitHub
commit b8bb000073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 314 additions and 44 deletions

View File

@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.
### BLUEPRINTS
- [[#1821](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1821)] [net-address] enable ipv6 ([LucaPrete](https://github.com/LucaPrete)) <!-- 2023-10-28 13:36:31+00:00 -->
- [[#1814](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1814)] **incompatible change:** Allow specifying arbitrary project roles for service accounts in project factory ([ludoo](https://github.com/ludoo)) <!-- 2023-10-26 14:09:04+00:00 -->
- [[#1812](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1812)] Stop wrapping yamldecode with try() ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-25 14:16:05+00:00 -->
- [[#1806](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1806)] Updating network dashboard: fixing Cloud SQL problem, fixing 1 metric… ([aurelienlegrand](https://github.com/aurelienlegrand)) <!-- 2023-10-25 10:37:25+00:00 -->
- [[#1796](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1796)] Make extended shared vpc attributes optional in project factory ([ludoo](https://github.com/ludoo)) <!-- 2023-10-23 13:45:48+00:00 -->
@ -25,6 +27,7 @@ All notable changes to this project will be documented in this file.
### FAST
- [[#1818](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1818)] FAST: rename VPC-related files to `net-*` ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-27 08:23:08+00:00 -->
- [[#1812](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1812)] Stop wrapping yamldecode with try() ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-25 14:16:05+00:00 -->
- [[#1810](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1810)] FAST: Add access transparency logs to the default sinks ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-24 20:09:01+00:00 -->
- [[#1809](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1809)] FAST: Add VPC serverless connector NAT ranges to hierarchical fw ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-24 19:46:04+00:00 -->
@ -46,6 +49,11 @@ All notable changes to this project will be documented in this file.
### MODULES
- [[#1822](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1822)] Billing budget factory ([ludoo](https://github.com/ludoo)) <!-- 2023-10-29 10:24:52+00:00 -->
- [[#1821](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1821)] [net-address] enable ipv6 ([LucaPrete](https://github.com/LucaPrete)) <!-- 2023-10-28 13:36:31+00:00 -->
- [[#1820](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1820)] Added iam_bindings and iam_bindings_additive to apigee module ([apichick](https://github.com/apichick)) <!-- 2023-10-27 18:08:18+00:00 -->
- [[#1813](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1813)] empty gpu sharing config fix ([ewojtach](https://github.com/ewojtach)) <!-- 2023-10-27 09:49:34+00:00 -->
- [[#1815](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1815)] Fix logic for default source range in firewall ingress rules ([ludoo](https://github.com/ludoo)) <!-- 2023-10-26 15:25:37+00:00 -->
- [[#1812](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1812)] Stop wrapping yamldecode with try() ([sruffilli](https://github.com/sruffilli)) <!-- 2023-10-25 14:16:05+00:00 -->
- [[#1750](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1750)] AI models support ([ewojtach](https://github.com/ewojtach)) <!-- 2023-10-25 09:42:37+00:00 -->
- [[#1798](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1798)] Fix Apigee add-ons configuration ([mwarm2](https://github.com/mwarm2)) <!-- 2023-10-25 07:37:45+00:00 -->

View File

@ -19,7 +19,9 @@ locals {
}
module "addresses" {
source = "../../../modules/net-address"
project_id = module.project.project_id
global_addresses = [local.ingress_ip_name]
source = "../../../modules/net-address"
project_id = module.project.project_id
global_addresses = {
"${local.ingress_ip_name}" = {}
}
}

View File

@ -19,7 +19,11 @@ locals {
}
module "addresses" {
source = "../../../modules/net-address"
project_id = module.project.project_id
global_addresses = ["grafana", "locust", "app"]
source = "../../../modules/net-address"
project_id = module.project.project_id
global_addresses = {
app = {}
grafana = {}
locust = {}
}
}

View File

@ -21,10 +21,12 @@ locals {
# Reserved static IP for the Load Balancer
module "addresses" {
source = "../../../modules/net-address"
count = local.glb_create ? 1 : 0
project_id = var.project_id
global_addresses = ["phpipam"]
source = "../../../modules/net-address"
count = local.glb_create ? 1 : 0
project_id = var.project_id
global_addresses = {
phpipam = {}
}
}
# Global L7 HTTPS Load Balancer in front of Cloud Run

View File

@ -23,6 +23,7 @@ provider "google" {
- [Billing budgets](#billing-budgets)
- [PubSub update rules](#pubsub-update-rules)
- [Monitoring channels](#monitoring-channels)
- [Budget factory](#budget-factory)
- [Variables](#variables)
- [Outputs](#outputs)
<!-- END TOC -->
@ -212,21 +213,63 @@ module "billing-account" {
# tftest modules=1 resources=2 inventory=budget-monitoring-channel.yaml
```
#### Budget factory
This module also exposes a factory for billing budgets, that works in a similar way to factories in other modules: a specific folder is searched for YAML files, which contain one budget description per file. The file name is used to generate the key of the resulting map of budgets, which is merged with the one coming from the `budgets` variable. The YAML files support the same type of the `budgets` variable.
```hcl
module "billing-account" {
source = "./fabric/modules/billing-account"
id = "012345-ABCDEF-012345"
budget_notification_channels = {
billing-default = {
project_id = "tf-playground-simple"
type = "email"
labels = {
email_address = "gcp-billing-admins@example.com"
}
}
}
}
# tftest modules=1 resources=2 files=test-1 inventory=budget-monitoring-channel.yaml
```
```yaml
# tftest-file id=test-1 path=data/billing-budgets/folder-net-month-current-100.yaml
display_name: 100 dollars in current spend
amount:
units: 100
filter:
period:
calendar: MONTH
resource_ancestors:
- folders/1234567890
threshold_rules:
- percent: 0.5
- percent: 0.75
update_rules:
default:
disable_default_iam_recipients: true
monitoring_notification_channels:
- billing-default
```
<!-- markdownlint-enable -->
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [id](variables.tf#L165) | Billing account id. | <code>string</code> | ✓ | |
| [id](variables.tf#L175) | Billing account id. | <code>string</code> | ✓ | |
| [budget_notification_channels](variables.tf#L17) | Notification channels used by budget alerts. | <code title="map&#40;object&#40;&#123;&#10; project_id &#61; string&#10; type &#61; string&#10; description &#61; optional&#40;string&#41;&#10; display_name &#61; optional&#40;string&#41;&#10; enabled &#61; optional&#40;bool, true&#41;&#10; force_delete &#61; optional&#40;bool&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;&#41;&#10; sensitive_labels &#61; optional&#40;list&#40;object&#40;&#123;&#10; auth_token &#61; optional&#40;string&#41;&#10; password &#61; optional&#40;string&#41;&#10; service_key &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#41;&#10; user_labels &#61; optional&#40;map&#40;string&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [budgets](variables.tf#L47) | Billing budgets. Notification channels are either keys in corresponding variable, or external ids. | <code title="map&#40;object&#40;&#123;&#10; amount &#61; object&#40;&#123;&#10; currency_code &#61; optional&#40;string&#41;&#10; nanos &#61; optional&#40;number&#41;&#10; units &#61; optional&#40;number&#41;&#10; use_last_period &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#10; display_name &#61; optional&#40;string&#41;&#10; filter &#61; optional&#40;object&#40;&#123;&#10; credit_types_treatment &#61; optional&#40;object&#40;&#123;&#10; exclude_all &#61; optional&#40;bool&#41;&#10; include_specified &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#10; label &#61; optional&#40;object&#40;&#123;&#10; key &#61; string&#10; value &#61; string&#10; &#125;&#41;&#41;&#10; period &#61; optional&#40;object&#40;&#123;&#10; calendar &#61; optional&#40;string&#41;&#10; custom &#61; optional&#40;object&#40;&#123;&#10; start_date &#61; object&#40;&#123;&#10; day &#61; number&#10; month &#61; number&#10; year &#61; number&#10; &#125;&#41;&#10; end_date &#61; optional&#40;object&#40;&#123;&#10; day &#61; number&#10; month &#61; number&#10; year &#61; number&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; projects &#61; optional&#40;list&#40;string&#41;&#41;&#10; resource_ancestors &#61; optional&#40;list&#40;string&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; subaccounts &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#10; threshold_rules &#61; optional&#40;list&#40;object&#40;&#123;&#10; percent &#61; number&#10; forecasted_spend &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;, &#91;&#93;&#41;&#10; update_rules &#61; optional&#40;map&#40;object&#40;&#123;&#10; disable_default_iam_recipients &#61; optional&#40;bool&#41;&#10; monitoring_notification_channels &#61; optional&#40;list&#40;string&#41;&#41;&#10; pubsub_topic &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [group_iam](variables.tf#L121) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L128) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings](variables.tf#L135) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; members &#61; list&#40;string&#41;&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings_additive](variables.tf#L150) | Individual additive IAM bindings. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [logging_sinks](variables.tf#L170) | Logging sinks to create for the organization. | <code title="map&#40;object&#40;&#123;&#10; destination &#61; string&#10; type &#61; string&#10; bq_partitioned_table &#61; optional&#40;bool&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; exclusions &#61; optional&#40;map&#40;object&#40;&#123;&#10; filter &#61; string&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; filter &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [projects](variables.tf#L203) | Projects associated with this billing account. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [factory_config](variables.tf#L121) | Path to folder containing budget alerts data files. | <code title="object&#40;&#123;&#10; budgets_data_path &#61; optional&#40;string, &#34;data&#47;billing-budgets&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [group_iam](variables.tf#L131) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L138) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings](variables.tf#L145) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; members &#61; list&#40;string&#41;&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings_additive](variables.tf#L160) | Individual additive IAM bindings. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [logging_sinks](variables.tf#L180) | Logging sinks to create for the organization. | <code title="map&#40;object&#40;&#123;&#10; destination &#61; string&#10; type &#61; string&#10; bq_partitioned_table &#61; optional&#40;bool&#41;&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; exclusions &#61; optional&#40;map&#40;object&#40;&#123;&#10; filter &#61; string&#10; description &#61; optional&#40;string&#41;&#10; disabled &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; filter &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [projects](variables.tf#L213) | Projects associated with this billing account. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
## Outputs

View File

@ -37,7 +37,7 @@ resource "google_monitoring_notification_channel" "default" {
}
resource "google_billing_budget" "default" {
for_each = var.budgets
for_each = merge(local.factory_budgets, var.budgets)
billing_account = var.id
display_name = each.value.display_name
dynamic "amount" {

View File

@ -0,0 +1,98 @@
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
_factory_data = {
for f in fileset("${local._factory_path}", "**/*.yaml") :
trimsuffix(f, ".yaml") => yamldecode(file("${local._factory_path}/${f}"))
}
_factory_path = var.factory_config.budgets_data_path
factory_budgets = {
for k, v in local._factory_data : k => merge(v, {
amount = merge(
{
currency_code = null
nanos = null
units = null
use_last_period = null
},
try(v.amount, {})
)
display_name = try(v.display_name, null)
filter = try(v.filter, null) == null ? null : {
credit_types_treatment = (
try(v.filter.credit_types_treatment, null) == null
? null
: merge(
{ exclude_all = null, include_specified = null },
v.filter.credit_types_treatment
)
)
label = try(v.filter.label, null)
projects = try(v.filter.projects, null)
resource_ancestors = try(v.filter.resource_ancestors, null)
services = try(v.filter.services, null)
subaccounts = try(v.filter.subaccounts, null)
}
threshold_rules = [
for vv in try(v.threshold_rules, []) : merge({
percent = null
forecasted_spend = null
}, vv)
]
update_rules = {
for kk, vv in try(v.update_rules, {}) : kk => merge({
disable_default_iam_recipients = null
monitoring_notification_channels = null
pubsub_topic = null
}, vv)
}
})
}
}
# check data coming from the factory as it bypasses variable validation rules
check "factory_budgets" {
assert {
condition = alltrue([
for k, v in local.factory_budgets : v.amount != null && (
try(v.amount.use_last_period, null) == true ||
try(v.amount.units, null) != null
)
])
error_message = "Factory budgets need either amount units or last period set."
}
assert {
condition = alltrue([
for k, v in local.factory_budgets :
v.threshold_rules == null || try(v.threshold_rules.percent, null) != null
])
error_message = "Threshold rules need percent set."
}
assert {
condition = alltrue(flatten([
for k, v in local.factory_budgets : [
for kk, vv in v.update_rules : [
vv.monitoring_notification_channels != null
||
vv.pubsub_topic != null
]
]
]))
error_message = "Notification rules need either a pubsub topic or monitoring channels defined."
}
}

View File

@ -118,6 +118,16 @@ variable "budgets" {
}
}
variable "factory_config" {
# TODO: align all other factory variable names
description = "Path to folder containing budget alerts data files."
type = object({
budgets_data_path = optional(string, "data/billing-budgets")
})
nullable = false
default = {}
}
variable "group_iam" {
description = "Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable."
type = map(list(string))

View File

@ -14,7 +14,10 @@ module "addresses" {
one = { region = "europe-west1" }
two = { region = "europe-west2" }
}
global_addresses = ["app-1", "app-2"]
global_addresses = {
app-1 = {}
app-2 = {}
}
}
# tftest modules=1 resources=4 inventory=external.yaml
```
@ -41,6 +44,40 @@ module "addresses" {
# tftest modules=1 resources=2 inventory=internal.yaml
```
### IPv6 addresses
You can reserve both external and internal IPv6 addresses.
```hcl
module "addresses" {
source = "./fabric/modules/net-address"
project_id = var.project_id
external_addresses = {
nlb = {
region = var.region
subnetwork = var.subnet.self_link
ipv6 = {
endpoint_type = "NETLB"
}
}
}
internal_addresses = {
ilb = {
ipv6 = {}
purpose = "SHARED_LOADBALANCER_VIP"
region = var.region
subnetwork = var.subnet.self_link
}
vm = {
ipv6 = {}
region = var.region
subnetwork = var.subnet.self_link
}
}
}
# tftest modules=1 resources=3 inventory=ipv6.yaml
```
### PSA addresses
```hcl
@ -106,13 +143,13 @@ module "addresses" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [project_id](variables.tf#L68) | Project where the addresses will be created. | <code>string</code> | ✓ | |
| [external_addresses](variables.tf#L17) | Map of external addresses, keyed by name. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [global_addresses](variables.tf#L28) | List of global addresses to create. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [internal_addresses](variables.tf#L34) | Map of internal addresses to create, keyed by name. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; subnetwork &#61; string&#10; address &#61; optional&#40;string&#41;&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;&#41;&#10; name &#61; optional&#40;string&#41;&#10; purpose &#61; optional&#40;string&#41;&#10; tier &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ipsec_interconnect_addresses](variables.tf#L49) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; address &#61; string&#10; network &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10; prefix_length &#61; number&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [psa_addresses](variables.tf#L73) | Map of internal addresses used for Private Service Access. | <code title="map&#40;object&#40;&#123;&#10; address &#61; string&#10; network &#61; string&#10; prefix_length &#61; number&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#10;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [psc_addresses](variables.tf#L86) | Map of internal addresses used for Private Service Connect. | <code title="map&#40;object&#40;&#123;&#10; address &#61; string&#10; network &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [project_id](variables.tf#L83) | Project where the addresses will be created. | <code>string</code> | ✓ | |
| [external_addresses](variables.tf#L17) | Map of external addresses, keyed by name. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; ipv6 &#61; optional&#40;object&#40;&#123;&#10; endpoint_type &#61; string&#10; &#125;&#41;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [global_addresses](variables.tf#L38) | List of global addresses to create. | <code title="map&#40;object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; ipv6 &#61; optional&#40;map&#40;string&#41;&#41; &#35; To be left empty for ipv6&#10; name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [internal_addresses](variables.tf#L48) | Map of internal addresses to create, keyed by name. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; subnetwork &#61; string&#10; address &#61; optional&#40;string&#41;&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; ipv6 &#61; optional&#40;map&#40;string&#41;&#41; &#35; To be left empty for ipv6&#10; labels &#61; optional&#40;map&#40;string&#41;&#41;&#10; name &#61; optional&#40;string&#41;&#10; purpose &#61; optional&#40;string&#41;&#10; tier &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ipsec_interconnect_addresses](variables.tf#L64) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | <code title="map&#40;object&#40;&#123;&#10; region &#61; string&#10; address &#61; string&#10; network &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10; prefix_length &#61; number&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [psa_addresses](variables.tf#L88) | Map of internal addresses used for Private Service Access. | <code title="map&#40;object&#40;&#123;&#10; address &#61; string&#10; network &#61; string&#10; prefix_length &#61; number&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#10;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [psc_addresses](variables.tf#L101) | Map of internal addresses used for Private Service Connect. | <code title="map&#40;object&#40;&#123;&#10; address &#61; string&#10; network &#61; string&#10; description &#61; optional&#40;string, &#34;Terraform managed.&#34;&#41;&#10; name &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs

View File

@ -15,20 +15,24 @@
*/
resource "google_compute_global_address" "global" {
for_each = toset(var.global_addresses)
project = var.project_id
name = each.value
for_each = var.global_addresses
project = var.project_id
name = coalesce(each.value.name, each.key)
description = each.value.description
ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
}
resource "google_compute_address" "external" {
provider = google-beta
for_each = var.external_addresses
project = var.project_id
name = coalesce(each.value.name, each.key)
description = each.value.description
address_type = "EXTERNAL"
region = each.value.region
labels = each.value.labels
provider = google-beta
for_each = var.external_addresses
project = var.project_id
name = coalesce(each.value.name, each.key)
description = each.value.description
address_type = "EXTERNAL"
ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
ipv6_endpoint_type = try(each.value.ipv6.endpoint_type, null)
region = each.value.region
labels = each.value.labels
}
resource "google_compute_address" "internal" {
@ -41,6 +45,7 @@ resource "google_compute_address" "internal" {
region = each.value.region
subnetwork = each.value.subnetwork
address = each.value.address
ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
network_tier = each.value.tier
purpose = each.value.purpose
labels = coalesce(each.value.labels, {})

View File

@ -19,16 +19,30 @@ variable "external_addresses" {
type = map(object({
region = string
description = optional(string, "Terraform managed.")
labels = optional(map(string), {})
name = optional(string)
ipv6 = optional(object({
endpoint_type = string
}))
labels = optional(map(string), {})
name = optional(string)
}))
default = {}
validation {
condition = (
try(var.external_addresses.ipv6, null) == null
|| can(regex("^(NETLB|VM)$", try(var.external_addresses.ipv6.endpoint_type, null)))
)
error_message = "IPv6 endpoint type must be NETLB, VM."
}
}
variable "global_addresses" {
description = "List of global addresses to create."
type = list(string)
default = []
type = map(object({
description = optional(string, "Terraform managed.")
ipv6 = optional(map(string)) # To be left empty for ipv6
name = optional(string)
}))
default = {}
}
variable "internal_addresses" {
@ -38,6 +52,7 @@ variable "internal_addresses" {
subnetwork = string
address = optional(string)
description = optional(string, "Terraform managed.")
ipv6 = optional(map(string)) # To be left empty for ipv6
labels = optional(map(string))
name = optional(string)
purpose = optional(string)

View File

@ -129,9 +129,11 @@ Redirect is implemented via an additional HTTP load balancer with a custom URL m
```hcl
module "addresses" {
source = "./fabric/modules/net-address"
project_id = "myprj"
global_addresses = ["glb-test-0"]
source = "./fabric/modules/net-address"
project_id = "myprj"
global_addresses = {
"glb-test-0" = {}
}
}
module "glb-test-0-redirect" {

View File

@ -0,0 +1,44 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
values:
module.addresses.google_compute_address.external["nlb"]:
address_type: EXTERNAL
ip_version: IPV6
ipv6_endpoint_type: NETLB
name: nlb
project: project-id
region: region
module.addresses.google_compute_address.internal["ilb"]:
address_type: INTERNAL
ip_version: IPV6
labels: null
name: ilb
network: null
project: project-id
purpose: SHARED_LOADBALANCER_VIP
region: region
subnetwork: subnet_self_link
module.addresses.google_compute_address.internal["vm"]:
address_type: INTERNAL
ip_version: IPV6
labels: null
name: vm
network: null
project: project-id
region: region
subnetwork: subnet_self_link
counts:
google_compute_address: 3