Refactor net-vpc module for Terraform 1.3 (#880)

* module tests pass

* doc examples

* refactor blueprints

* fast stages

* fix comment typo

* fix module factory test
This commit is contained in:
Ludovico Magnocavallo
2022-10-14 11:02:33 +02:00
committed by GitHub
parent 1ead60122d
commit 4fa1dc431d
57 changed files with 419 additions and 594 deletions

View File

@@ -15,9 +15,9 @@
region: europe-west1
description: Sample description
ip_cidr_range: 10.128.0.0/24
private_ip_google_access: false
enable_private_access: false
iam_users: ["foobar@example.com"]
iam_groups: ["lorem@example.com"]
iam_service_accounts: ["foobar@project-id.iam.gserviceaccount.com"]
secondary_ip_range:
secondary_ip_ranges:
secondary-range-a: 192.168.128.0/24

View File

@@ -16,19 +16,14 @@
module "test" {
source = "../../../../modules/net-vpc"
project_id = var.project_id
name = var.name
iam = var.iam
log_configs = var.log_configs
log_config_defaults = var.log_config_defaults
project_id = "test-project"
name = "test"
peering_config = var.peering_config
routes = var.routes
shared_vpc_host = var.shared_vpc_host
shared_vpc_service_projects = var.shared_vpc_service_projects
subnet_iam = var.subnet_iam
subnets = var.subnets
subnet_descriptions = var.subnet_descriptions
subnet_flow_logs = var.subnet_flow_logs
subnet_private_access = var.subnet_private_access
auto_create_subnetworks = var.auto_create_subnetworks
psa_config = var.psa_config
data_folder = var.data_folder

View File

@@ -14,110 +14,88 @@
* limitations under the License.
*/
variable "project_id" {
type = string
default = "my-project"
}
variable "name" {
type = string
default = "my-vpc"
}
variable "auto_create_subnetworks" {
type = bool
default = false
}
variable "iam" {
type = map(map(set(string)))
variable "data_folder" {
type = string
default = null
}
variable "log_configs" {
variable "delete_default_routes_on_create" {
type = bool
default = false
}
variable "description" {
type = string
default = "Terraform-managed."
}
variable "dns_policy" {
type = any
default = null
}
variable "log_config_defaults" {
type = any
default = {
aggregation_interval = "INTERVAL_5_SEC"
flow_sampling = 0.5
metadata = "INCLUDE_ALL_METADATA"
}
variable "mtu" {
type = number
default = null
}
variable "peering_config" {
type = object({
peer_vpc_self_link = string
export_routes = bool
import_routes = bool
})
type = any
default = null
}
variable "psa_config" {
description = "The Private Service Access configuration."
type = any
default = null
}
variable "routes" {
type = any
default = null
}
variable "routes" {
type = any
default = {}
nullable = false
}
variable "routing_mode" {
description = "The network routing mode (default 'GLOBAL')."
type = string
default = "GLOBAL"
type = string
default = "GLOBAL"
}
variable "shared_vpc_host" {
description = "Enable shared VPC for this project."
type = bool
default = false
type = bool
default = false
}
variable "shared_vpc_service_projects" {
description = "Shared VPC service projects to register with this host."
type = list(string)
default = []
type = list(string)
default = []
}
variable "subnets" {
description = "The list of subnets being created."
type = any
default = []
type = any
default = []
}
variable "subnet_descriptions" {
description = "Optional map of subnet descriptions, keyed by subnet name."
type = map(string)
default = {}
variable "subnet_iam" {
type = map(map(list(string)))
default = {}
}
variable "subnet_flow_logs" {
description = "Optional map of boolean to control flow logs (default is disabled), keyed by subnet name."
type = map(bool)
default = {}
variable "subnets_proxy_only" {
type = any
default = []
}
variable "subnet_private_access" {
description = "Optional map of boolean to control private Google access (default is enabled), keyed by subnet name."
type = map(bool)
default = {}
variable "subnets_psc" {
type = any
default = []
}
variable "private_service_networking_range" {
description = "RFC1919 CIDR range used for Google services that support private service networking."
type = string
default = null
}
variable "data_folder" {
description = "An optional folder containing the subnet configurations in YaML format."
type = string
default = null
variable "vpc_create" {
type = bool
default = true
}

View File

@@ -12,23 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
_VAR_PEER_VPC_CONFIG = (
'{'
'peer_vpc_self_link="projects/my-project/global/networks/my-peer-vpc", '
'export_routes=true, import_routes=null'
'}'
)
_VAR_ROUTES_TEMPLATE = (
'{'
' next-hop-test = {'
' dest_range="192.168.128.0/24", priority=1000, tags=null, '
' next_hop_type="%s", next_hop="%s"},'
' gateway-test = {'
' dest_range="0.0.0.0/0", priority=100, tags=["tag-a"], '
' next_hop_type="gateway", '
' next_hop="global/gateways/default-internet-gateway"}'
'}'
)
_VAR_PEER_VPC_CONFIG = '''{
peer_vpc_self_link="projects/my-project/global/networks/peer",
export_routes=true, import_routes=null
}'''
_VAR_ROUTES_TEMPLATE = '''{
next-hop = {
dest_range="192.168.128.0/24", tags=null,
next_hop_type="%s", next_hop="%s"},
gateway = {
dest_range="0.0.0.0/0", priority=100, tags=["tag-a"],
next_hop_type="gateway",
next_hop="global/gateways/default-internet-gateway"}
}'''
_VAR_ROUTES_NEXT_HOPS = {
'gateway': 'global/gateways/default-internet-gateway',
'instance': 'zones/europe-west1-b/test',
@@ -43,8 +39,8 @@ def test_vpc_simple(plan_runner):
_, resources = plan_runner()
assert len(resources) == 1
assert [r['type'] for r in resources] == ['google_compute_network']
assert [r['values']['name'] for r in resources] == ['my-vpc']
assert [r['values']['project'] for r in resources] == ['my-project']
assert [r['values']['name'] for r in resources] == ['test']
assert [r['values']['project'] for r in resources] == ['test-project']
def test_vpc_shared(plan_runner):
@@ -62,13 +58,14 @@ def test_vpc_peering(plan_runner):
"Test vpc peering variables."
_, resources = plan_runner(peering_config=_VAR_PEER_VPC_CONFIG)
assert len(resources) == 3
assert set(r['type'] for r in resources) == set([
'google_compute_network', 'google_compute_network_peering'
])
peerings = [r['values']
for r in resources if r['type'] == 'google_compute_network_peering']
assert [p['name'] for p in peerings] == [
'my-vpc-my-peer-vpc', 'my-peer-vpc-my-vpc']
assert set(r['type'] for r in resources) == set(
['google_compute_network', 'google_compute_network_peering'])
peerings = [
r['values']
for r in resources
if r['type'] == 'google_compute_network_peering'
]
assert [p['name'] for p in peerings] == ['test-peer', 'peer-test']
assert [p['export_custom_routes'] for p in peerings] == [True, False]
assert [p['import_custom_routes'] for p in peerings] == [False, True]
@@ -79,6 +76,6 @@ def test_vpc_routes(plan_runner):
_var_routes = _VAR_ROUTES_TEMPLATE % (next_hop_type, next_hop)
_, resources = plan_runner(routes=_var_routes)
assert len(resources) == 3
resource = [r for r in resources if r['values']
['name'] == 'my-vpc-next-hop-test'][0]
resource = [r for r in resources if r['values']['name'] == 'test-next-hop'
][0]
assert resource['values']['next_hop_%s' % next_hop_type]

View File

@@ -35,11 +35,9 @@ def test_routes_export(plan_runner):
psa_config = '''{
ranges = {
bar = "172.16.100.0/24"
},
routes = {
export = true
import = false
}
export_routes = true
import_routes = false
}'''
_, resources = plan_runner(psa_config=psa_config)
assert len(resources) == 4
@@ -55,10 +53,8 @@ def test_routes_import(plan_runner):
ranges = {
bar = "172.16.100.0/24"
},
routes = {
export = false
import = true
}
export_routes = false
import_routes = true
}'''
_, resources = plan_runner(psa_config=psa_config)
for r in resources:
@@ -73,10 +69,8 @@ def test_routes_export_import(plan_runner):
ranges = {
bar = "172.16.100.0/24"
},
routes = {
export = true
import = true
}
export_routes = true
import_routes = true
}'''
_, resources = plan_runner(psa_config=psa_config)
for r in resources:

View File

@@ -12,73 +12,87 @@
# See the License for the specific language governing permissions and
# limitations under the License.
_VAR_SUBNETS = (
'[ '
'{name = "a", region = "europe-west1", ip_cidr_range = "10.0.0.0/24",'
' secondary_ip_range=null},'
'{name = "b", region = "europe-west1", ip_cidr_range = "10.0.1.0/24",'
' secondary_ip_range=null},'
'{name = "c", region = "europe-west1", ip_cidr_range = "10.0.2.0/24",'
' secondary_ip_range={a="192.168.0.0/24", b="192.168.1.0/24"}},'
']')
_VAR_DATA_FOLDER = "data"
DATA_FOLDER = "data"
SUBNET_IAM = '''{
"europe-west1/a" = {
"roles/compute.networkUser" = ["user:a@example.com", "group:g-a@example.com"]
}
"europe-west1/c" = {
"roles/compute.networkUser" = ["user:c@example.com", "group:g-c@example.com"]
}
}'''
SUBNETS = '''[
{
name = "a", region = "europe-west1", ip_cidr_range = "10.0.0.0/24"
},
{
name = "b", region = "europe-west1", ip_cidr_range = "10.0.1.0/24",
description="Subnet b", enable_private_access=false
},
{
name = "c", region = "europe-west1", ip_cidr_range = "10.0.2.0/24",
secondary_ip_ranges={a="192.168.0.0/24", b="192.168.1.0/24"}
},
{
name = "d", region = "europe-west1", ip_cidr_range = "10.0.3.0/24",
flow_logs_config = {
flow_sampling = 0.5, aggregation_interval = "INTERVAL_10_MIN"
}
},
]'''
def test_subnet_factory(plan_runner):
"Test subnet factory."
_, resources = plan_runner(data_folder=_VAR_DATA_FOLDER)
_, resources = plan_runner(data_folder=DATA_FOLDER)
assert len(resources) == 3
subnets = [
r['values'] for r in resources if r['type'] == 'google_compute_subnetwork'
]
assert {s['name'] for s in subnets} == {'factory-subnet', 'factory-subnet2'}
assert {len(s['secondary_ip_range']) for s in subnets} == {0, 1}
assert {s['private_ip_google_access'] for s in subnets} == {True, False}
def test_subnets_simple(plan_runner):
def test_subnets(plan_runner):
"Test subnets variable."
_, resources = plan_runner(subnets=_VAR_SUBNETS)
assert len(resources) == 4
_, resources = plan_runner(subnet_iam=SUBNET_IAM, subnets=SUBNETS)
assert len(resources) == 7
subnets = [
r['values'] for r in resources if r['type'] == 'google_compute_subnetwork'
]
assert {s['name'] for s in subnets} == {'a', 'b', 'c'}
assert {len(s['secondary_ip_range']) for s in subnets} == {0, 0, 2}
def test_subnet_log_configs(plan_runner):
"Test subnets flow logs configuration and defaults."
log_config = '{"europe-west1/a" = { flow_sampling = 0.1 }}'
log_config_defaults = (
'{aggregation_interval = "INTERVAL_10_MIN", flow_sampling = 0.5, '
'metadata = "INCLUDE_ALL_METADATA"}')
subnet_flow_logs = '{"europe-west1/a"=true, "europe-west1/b"=true}'
_, resources = plan_runner(subnets=_VAR_SUBNETS, log_configs=log_config,
log_config_defaults=log_config_defaults,
subnet_flow_logs=subnet_flow_logs)
assert len(resources) == 4
flow_logs = {}
for r in resources:
if r['type'] != 'google_compute_subnetwork':
continue
flow_logs[r['values']['name']] = [{
key: config[key] for key in config.keys() &
{'aggregation_interval', 'flow_sampling', 'metadata'}
} for config in r['values']['log_config']]
assert flow_logs == {
# enable, override one default option
'a': [{
'aggregation_interval': 'INTERVAL_10_MIN',
'flow_sampling': 0.1,
'metadata': 'INCLUDE_ALL_METADATA'
}],
# enable, use defaults
'b': [{
assert {s['name'] for s in subnets} == {'a', 'b', 'c', 'd'}
assert {len(s['secondary_ip_range']) for s in subnets} == {0, 0, 2, 0}
log_config = {s['name']: s['log_config'] for s in subnets if s['log_config']}
assert log_config == {
'd': [{
'aggregation_interval': 'INTERVAL_10_MIN',
'filter_expr': 'true',
'flow_sampling': 0.5,
'metadata': 'INCLUDE_ALL_METADATA'
}],
# don't enable
'c': []
'metadata': 'INCLUDE_ALL_METADATA',
'metadata_fields': None
}]
}
bindings = {
r['index']: r['values']
for r in resources
if r['type'] == 'google_compute_subnetwork_iam_binding'
}
assert bindings == {
'europe-west1/a.roles/compute.networkUser': {
'condition': [],
'members': ['group:g-a@example.com', 'user:a@example.com'],
'project': 'test-project',
'region': 'europe-west1',
'role': 'roles/compute.networkUser',
'subnetwork': 'a'
},
'europe-west1/c.roles/compute.networkUser': {
'condition': [],
'members': ['group:g-c@example.com', 'user:c@example.com'],
'project': 'test-project',
'region': 'europe-west1',
'role': 'roles/compute.networkUser',
'subnetwork': 'c'
},
}