Shared VPC example (#13)
Simple Shared VPC example with test resources.
This commit is contained in:
committed by
GitHub
parent
f7d950b39f
commit
ddb8c70f79
@@ -19,19 +19,26 @@ steps:
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
python -m pip install --user -r tests/requirements.txt &&
|
||||
python -m pip install --user --no-warn-script-location -r tests/requirements.txt &&
|
||||
wget https://releases.hashicorp.com/terraform/${_TERRAFORM_VERSION}/terraform_${_TERRAFORM_VERSION}_linux_amd64.zip &&
|
||||
unzip terraform_${_TERRAFORM_VERSION}_linux_amd64.zip -d /builder/home/.local/bin &&
|
||||
rm terraform_${_TERRAFORM_VERSION}_linux_amd64.zip &&
|
||||
chmod 755 /builder/home/.local/bin/terraform
|
||||
# TODO(ludoo): split into two triggers with different filters
|
||||
- name: python:3.6-alpine
|
||||
id: test
|
||||
entrypoint: python
|
||||
id: test-foundations
|
||||
entrypoint: pytest
|
||||
args:
|
||||
- -m
|
||||
- pytest
|
||||
- -v
|
||||
- tests
|
||||
- tests/foundations
|
||||
env:
|
||||
- PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin
|
||||
- name: python:3.6-alpine
|
||||
id: test-infrastructure
|
||||
entrypoint: pytest
|
||||
args:
|
||||
- -v
|
||||
- tests/infrastructure
|
||||
env:
|
||||
- PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin
|
||||
|
||||
|
||||
65
infrastructure/shared-vpc/README.md
Normal file
65
infrastructure/shared-vpc/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Shared VPC sample
|
||||
|
||||
This sample creates a basic [Shared VPC](https://cloud.google.com/vpc/docs/shared-vpc) infrastructure, where two service projects are connected to separate subnets, and the host project exposes Cloud DNS and Cloud KMS as centralized services. The service projects are slightly different, as they are meant to illustrate the IAM-level differences that need to be taken into account when sharing subnets for GCE or GKE.
|
||||
|
||||
The purpose of this sample is showing how to wire different [Cloud Foundation Fabric](https://github.com/search?q=topic%3Acft-fabric+org%3Aterraform-google-modules&type=Repositories) modules to create Shared VPC infrastructures, and as such it is meant to be used for prototyping, or to experiment with networking configurations. Additional best practices and security considerations need to be taken into account for real world usage (eg removal of default service accounts, disabling of external IPs, firewall design, etc).
|
||||
|
||||

|
||||
|
||||
## Managed resources and services
|
||||
|
||||
This sample creates several distinct groups of resources:
|
||||
|
||||
- three projects (Shared VPC host and two service projects)
|
||||
- VPC-level resources (VPC, subnets, firewall rules, etc.) in the host project
|
||||
- one internal Cloud DNS zone in the host project
|
||||
- one Cloud KMS keyring with one key in the host project
|
||||
- IAM roles to wire all the above resource together
|
||||
- one test instance in each project, with their associated DNS records
|
||||
|
||||
## Test resources
|
||||
|
||||
A set of test resources are included for convenience, as they facilitate experimenting with different networking configurations (firewall rules, external connectivity via VPN, etc.). They are encapsulated in the `test-resources.tf` file, and can be safely removed as a single unit.
|
||||
|
||||
SSH access to instances is configured via [OS Login](https://cloud.google.com/compute/docs/oslogin/), except for the GKE project instance since [GKE nodes do not support OS Login](https://cloud.google.com/compute/docs/instances/managing-instance-access#limitations). To access the GKe instance, use a SSH key set at the project or instance level. External access is allowed via the default SSH rule created by the firewall module, and corresponding `ssh` tags on the instances.
|
||||
|
||||
The GCE instance is somewhat special, as it's configured to run a containerized MySQL server using the [`cos-mysql` module](https://github.com/terraform-google-modules/terraform-google-container-vm/tree/master/modules/cos-mysql), to show a practical example of using this module with KMS encryption for its secret, and to demonstrate how to define a custom firewall rule in the firewall module.
|
||||
|
||||
The networking and GKE instances have `dig` and the `mysql` client installed via startup scripts, so that tests can be run as soon as they are created.
|
||||
|
||||
## Destroying
|
||||
|
||||
There's a minor glitch that can surface running `terraform destroy`, with a simple workaround. The glitch is due to a delay between the API reporting service project removal from the Shared VPC as successful (`google_compute_shared_vpc_service_project` resources destroyed), and the Shared VPC resource being aligned with that event. This results in an error that prevents disabling the Shared VPC feature: `Error disabling Shared VPC Host [...] Cannot disable project as a shared VPC host because it has active service projects.`. The workaround is to run `terraform destroy` again after a few seconds, giving the Shared VPC resource time to be in sync with service project removal.
|
||||
|
||||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|:----:|:-----:|:-----:|
|
||||
| billing\_account\_id | Billing account id used as default for new projects. | string | n/a | yes |
|
||||
| kms\_keyring\_location | Location used for the KMS keyring. | string | `"europe"` | no |
|
||||
| kms\_keyring\_name | Name used for the KMS keyring. | string | `"svpc-example"` | no |
|
||||
| oslogin\_admins\_gce | GCE project oslogin admin members, in IAM format. | list | `<list>` | no |
|
||||
| oslogin\_users\_gce | GCE project oslogin user members, in IAM format. | list | `<list>` | no |
|
||||
| owners\_gce | GCE project owners, in IAM format. | list | `<list>` | no |
|
||||
| owners\_gke | GKE project owners, in IAM format. | list | `<list>` | no |
|
||||
| owners\_host | Host project owners, in IAM format. | list | `<list>` | no |
|
||||
| prefix | Prefix used for resources that need unique names. | string | n/a | yes |
|
||||
| project\_services | Service APIs enabled by default in new projects. | list | `<list>` | no |
|
||||
| root\_node | Hierarchy node where projects will be created, 'organizations/org_id' or 'folders/folder_id'. | string | n/a | yes |
|
||||
| subnet\_secondary\_ranges | Shared VPC subnets secondary range definitions. | map | `<map>` | no |
|
||||
| subnets | Shared VPC subnet definitions. | list | `<list>` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| mysql-root-password | Password for the test MySQL db root user. |
|
||||
| net-vpc-name | Shared VPC name |
|
||||
| net-vpc-subnets | Shared VPC subnets. |
|
||||
| project-gce | GCE service project. |
|
||||
| project-gke | GKE service project. |
|
||||
| project-host | VPC host project. |
|
||||
| test-instances | Test instance names. |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
20
infrastructure/shared-vpc/backend.tf.sample
Normal file
20
infrastructure/shared-vpc/backend.tf.sample
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
|
||||
terraform {
|
||||
backend "gcs" {
|
||||
bucket = ""
|
||||
}
|
||||
}
|
||||
49
infrastructure/shared-vpc/diagram.gcpdraw
Normal file
49
infrastructure/shared-vpc/diagram.gcpdraw
Normal file
@@ -0,0 +1,49 @@
|
||||
elements {
|
||||
gcp {
|
||||
|
||||
group project_host {
|
||||
name "Host project"
|
||||
|
||||
group host_services {
|
||||
name "Shared Services"
|
||||
background_color "#f6f6f6"
|
||||
card dns
|
||||
card kms
|
||||
}
|
||||
|
||||
group vpc_host {
|
||||
name "Shared VPC"
|
||||
background_color "#fff3e0"
|
||||
card vpc as net_subnet {
|
||||
name "Networking subnet"
|
||||
}
|
||||
card vpc as gce_subnet {
|
||||
name "GCE subnet"
|
||||
}
|
||||
card vpc as gke_subnet {
|
||||
name "GKE subnet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group project_gce {
|
||||
name "GCE service project"
|
||||
stacked_card gce as gce_instances {
|
||||
name "VM instances"
|
||||
}
|
||||
}
|
||||
|
||||
group project_gke {
|
||||
name "GKE service project"
|
||||
stacked_card gke as gke_clusters {
|
||||
name "GKE clusters"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
paths {
|
||||
gce_subnet ..> gce_instances
|
||||
gke_subnet ..> gke_clusters
|
||||
}
|
||||
BIN
infrastructure/shared-vpc/diagram.png
Normal file
BIN
infrastructure/shared-vpc/diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
58
infrastructure/shared-vpc/locals.tf
Normal file
58
infrastructure/shared-vpc/locals.tf
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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 {
|
||||
# GCE service project users that need the network user role assigned on host
|
||||
net_gce_users = concat(
|
||||
var.owners_gce,
|
||||
["serviceAccount:${module.project-service-gce.cloudsvc_service_account}"]
|
||||
)
|
||||
# GKE service project users that need the network user role assigned on host
|
||||
net_gke_users = concat(
|
||||
var.owners_gke,
|
||||
[
|
||||
"serviceAccount:${module.project-service-gke.gke_service_account}",
|
||||
"serviceAccount:${module.project-service-gke.cloudsvc_service_account}"
|
||||
]
|
||||
)
|
||||
# GKE subnet primary and secondary ranges, used in firewall rules
|
||||
# use lookup to prevent failure on successive destroys
|
||||
net_gke_ip_ranges = compact([
|
||||
lookup(local.net_subnet_ips, "gke", ""),
|
||||
element([
|
||||
for range in lookup(var.subnet_secondary_ranges, "gke", []) :
|
||||
range.ip_cidr_range if range.range_name == "pods"
|
||||
], 0)
|
||||
])
|
||||
# map of subnet names => addresses
|
||||
net_subnet_ips = zipmap(
|
||||
module.net-vpc-host.subnets_names,
|
||||
module.net-vpc-host.subnets_ips
|
||||
)
|
||||
# map of subnet names => links
|
||||
net_subnet_links = zipmap(
|
||||
module.net-vpc-host.subnets_names,
|
||||
module.net-vpc-host.subnets_self_links
|
||||
)
|
||||
# map of subnet names => regions
|
||||
net_subnet_regions = zipmap(
|
||||
module.net-vpc-host.subnets_names,
|
||||
module.net-vpc-host.subnets_regions
|
||||
)
|
||||
# use svpc access module outputs to create an implicit dependency on service project registration
|
||||
service_projects = zipmap(
|
||||
module.net-svpc-access.service_projects,
|
||||
module.net-svpc-access.service_projects
|
||||
)
|
||||
}
|
||||
155
infrastructure/shared-vpc/main.tf
Normal file
155
infrastructure/shared-vpc/main.tf
Normal file
@@ -0,0 +1,155 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
###############################################################################
|
||||
# Host and service projects #
|
||||
###############################################################################
|
||||
|
||||
# host project
|
||||
|
||||
module "project-svpc-host" {
|
||||
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
|
||||
version = "3.3.0"
|
||||
parent = var.root_node
|
||||
prefix = var.prefix
|
||||
name = "vpc-host"
|
||||
billing_account = var.billing_account_id
|
||||
owners = var.owners_host
|
||||
activate_apis = var.project_services
|
||||
}
|
||||
|
||||
# service projects
|
||||
|
||||
module "project-service-gce" {
|
||||
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
|
||||
version = "3.3.0"
|
||||
parent = var.root_node
|
||||
prefix = var.prefix
|
||||
name = "gce"
|
||||
billing_account = var.billing_account_id
|
||||
oslogin = "true"
|
||||
owners = var.owners_gce
|
||||
oslogin_admins = var.oslogin_admins_gce
|
||||
oslogin_users = var.oslogin_users_gce
|
||||
activate_apis = var.project_services
|
||||
}
|
||||
|
||||
module "project-service-gke" {
|
||||
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
|
||||
version = "3.3.0"
|
||||
parent = var.root_node
|
||||
prefix = var.prefix
|
||||
name = "gke"
|
||||
billing_account = var.billing_account_id
|
||||
owners = var.owners_gke
|
||||
activate_apis = var.project_services
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Networking #
|
||||
################################################################################
|
||||
|
||||
# Shared VPC
|
||||
|
||||
module "net-vpc-host" {
|
||||
source = "terraform-google-modules/network/google"
|
||||
version = "1.4.0"
|
||||
project_id = module.project-svpc-host.project_id
|
||||
network_name = "vpc-shared"
|
||||
shared_vpc_host = true
|
||||
subnets = var.subnets
|
||||
secondary_ranges = var.subnet_secondary_ranges
|
||||
routes = []
|
||||
}
|
||||
|
||||
# Shared VPC firewall
|
||||
|
||||
module "net-vpc-firewall" {
|
||||
source = "terraform-google-modules/network/google//modules/fabric-net-firewall"
|
||||
version = "1.4.0"
|
||||
project_id = module.project-svpc-host.project_id
|
||||
network = module.net-vpc-host.network_name
|
||||
admin_ranges_enabled = true
|
||||
admin_ranges = compact([lookup(local.net_subnet_ips, "networking", "")])
|
||||
custom_rules = {
|
||||
ingress-mysql = {
|
||||
description = "Allow incoming connections on the MySQL port from GKE addresses."
|
||||
direction = "INGRESS"
|
||||
action = "allow"
|
||||
ranges = local.net_gke_ip_ranges
|
||||
sources = []
|
||||
targets = ["mysql"]
|
||||
use_service_accounts = false
|
||||
rules = [{ protocol = "tcp", ports = [3306] }]
|
||||
extra_attributes = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Shared VPC access
|
||||
|
||||
module "net-svpc-access" {
|
||||
source = "terraform-google-modules/network/google//modules/fabric-net-svpc-access"
|
||||
version = "1.4.0"
|
||||
host_project_id = module.project-svpc-host.project_id
|
||||
service_project_num = 2
|
||||
service_project_ids = [
|
||||
module.project-service-gce.project_id, module.project-service-gke.project_id
|
||||
]
|
||||
host_subnets = ["gce", "gke"]
|
||||
host_subnet_regions = compact([
|
||||
lookup(local.net_subnet_regions, "gce", ""),
|
||||
lookup(local.net_subnet_regions, "gke", "")
|
||||
])
|
||||
host_subnet_users = {
|
||||
gce = join(",", local.net_gce_users)
|
||||
gke = join(",", local.net_gke_users)
|
||||
}
|
||||
host_service_agent_role = true
|
||||
host_service_agent_users = [
|
||||
"serviceAccount:${module.project-service-gke.gke_service_account}"
|
||||
]
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# DNS #
|
||||
################################################################################
|
||||
|
||||
module "host-dns" {
|
||||
source = "terraform-google-modules/cloud-dns/google"
|
||||
version = "2.0.0"
|
||||
project_id = module.project-svpc-host.project_id
|
||||
type = "private"
|
||||
name = "svpc-fabric-example"
|
||||
domain = "svpc.fabric."
|
||||
private_visibility_config_networks = [module.net-vpc-host.network_self_link]
|
||||
record_names = ["localhost"]
|
||||
record_data = [{ rrdatas = "127.0.0.1", type = "A" }]
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# KMS #
|
||||
################################################################################
|
||||
|
||||
module "host-kms" {
|
||||
source = "terraform-google-modules/kms/google"
|
||||
version = "1.1.0"
|
||||
project_id = module.project-svpc-host.project_id
|
||||
location = var.kms_keyring_location
|
||||
keyring = var.kms_keyring_name
|
||||
keys = ["mysql"]
|
||||
set_decrypters_for = ["mysql"]
|
||||
decrypters = ["serviceAccount:${module.project-service-gce.gce_service_account}"]
|
||||
prevent_destroy = false
|
||||
}
|
||||
36
infrastructure/shared-vpc/outputs.tf
Normal file
36
infrastructure/shared-vpc/outputs.tf
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
output "vpc_name" {
|
||||
description = "Shared VPC name"
|
||||
value = module.net-vpc-host.network_name
|
||||
}
|
||||
|
||||
output "vpc_subnets" {
|
||||
description = "Shared VPC subnets."
|
||||
value = local.net_subnet_ips
|
||||
}
|
||||
|
||||
output "host_project_id" {
|
||||
description = "VPC host project id."
|
||||
value = module.project-svpc-host.project_id
|
||||
}
|
||||
|
||||
output "service_project_ids" {
|
||||
description = "Service project ids."
|
||||
value = {
|
||||
gce = module.project-service-gce.project_id
|
||||
gke = module.project-service-gke.project_id
|
||||
}
|
||||
}
|
||||
167
infrastructure/shared-vpc/test-resources.tf
Normal file
167
infrastructure/shared-vpc/test-resources.tf
Normal file
@@ -0,0 +1,167 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
###############################################################################
|
||||
# host test VM and DNS record #
|
||||
###############################################################################
|
||||
|
||||
resource "google_compute_instance" "test-net" {
|
||||
project = module.project-svpc-host.project_id
|
||||
name = "test-net"
|
||||
machine_type = "f1-micro"
|
||||
zone = "${local.net_subnet_regions.networking}-b"
|
||||
tags = ["ssh"]
|
||||
boot_disk {
|
||||
initialize_params {
|
||||
image = "debian-cloud/debian-9"
|
||||
}
|
||||
}
|
||||
network_interface {
|
||||
network = module.net-vpc-host.network_self_link
|
||||
subnetwork = local.net_subnet_links.networking
|
||||
access_config {}
|
||||
}
|
||||
metadata_startup_script = "apt update && apt install -y dnsutils mysql-client"
|
||||
}
|
||||
|
||||
resource "google_dns_record_set" "test_net" {
|
||||
project = module.project-svpc-host.project_id
|
||||
name = "test-net.${module.host-dns.domain}"
|
||||
type = "A"
|
||||
ttl = 300
|
||||
managed_zone = module.host-dns.name
|
||||
rrdatas = [
|
||||
google_compute_instance.test-net.network_interface.0.network_ip
|
||||
]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# GKE project test VM and DNS record #
|
||||
###############################################################################
|
||||
|
||||
resource "google_compute_instance" "test-gke" {
|
||||
depends_on = [module.net-svpc-access]
|
||||
project = module.project-service-gke.project_id
|
||||
name = "test-gke"
|
||||
machine_type = "f1-micro"
|
||||
zone = "${local.net_subnet_regions.gke}-b"
|
||||
tags = ["ssh"]
|
||||
boot_disk {
|
||||
initialize_params {
|
||||
image = "debian-cloud/debian-9"
|
||||
}
|
||||
}
|
||||
network_interface {
|
||||
network = module.net-vpc-host.network_self_link
|
||||
subnetwork = local.net_subnet_links.gke
|
||||
access_config {}
|
||||
}
|
||||
metadata_startup_script = "apt update && apt install -y dnsutils mysql-client"
|
||||
}
|
||||
|
||||
resource "google_dns_record_set" "test_gke" {
|
||||
project = module.project-svpc-host.project_id
|
||||
name = "test-gke.${module.host-dns.domain}"
|
||||
type = "A"
|
||||
ttl = 300
|
||||
managed_zone = module.host-dns.name
|
||||
rrdatas = [
|
||||
google_compute_instance.test-gke.network_interface.0.network_ip
|
||||
]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# GCE project MySQL test VM and DNS record #
|
||||
###############################################################################
|
||||
|
||||
# random password for MySQL
|
||||
|
||||
resource "random_pet" "mysql_password" {}
|
||||
|
||||
# MySQL password encrypted via KMS key
|
||||
|
||||
data "google_kms_secret_ciphertext" "mysql_password" {
|
||||
crypto_key = module.host-kms.keys.mysql
|
||||
plaintext = random_pet.mysql_password.id
|
||||
}
|
||||
|
||||
# work around the encrypted password always refreshing, taint to refresh
|
||||
|
||||
resource "null_resource" "mysql_password" {
|
||||
triggers = {
|
||||
ciphertext = data.google_kms_secret_ciphertext.mysql_password.ciphertext
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [triggers]
|
||||
}
|
||||
}
|
||||
|
||||
# MySQL container on Container Optimized OS
|
||||
|
||||
module "container-vm_cos-mysql" {
|
||||
source = "terraform-google-modules/container-vm/google//modules/cos-mysql"
|
||||
version = "1.0.4"
|
||||
project_id = lookup(local.service_projects, module.project-service-gce.project_id, "")
|
||||
region = "${lookup(local.net_subnet_regions, "gce", "")}"
|
||||
zone = "${lookup(local.net_subnet_regions, "gce", "")}-b"
|
||||
network = module.net-vpc-host.network_self_link
|
||||
subnetwork = lookup(local.net_subnet_links, "gke", "")
|
||||
instance_count = "1"
|
||||
data_disk_size = "10"
|
||||
vm_tags = ["ssh", "mysql"]
|
||||
password = null_resource.mysql_password.triggers.ciphertext
|
||||
# TODO(ludomagno): add a location output to the keyring module
|
||||
kms_data = {
|
||||
key = "mysql"
|
||||
keyring = module.host-kms.keyring_name
|
||||
location = var.kms_keyring_location
|
||||
project_id = module.project-svpc-host.project_id
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_dns_record_set" "mysql" {
|
||||
project = module.project-svpc-host.project_id
|
||||
name = "mysql.${module.host-dns.domain}"
|
||||
type = "A"
|
||||
ttl = 300
|
||||
managed_zone = module.host-dns.name
|
||||
rrdatas = [
|
||||
values(module.container-vm_cos-mysql.instances)[0]
|
||||
]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# test outputs #
|
||||
###############################################################################
|
||||
|
||||
output "test-instances" {
|
||||
description = "Test instance names."
|
||||
value = {
|
||||
gke = map(
|
||||
google_compute_instance.test-gke.name,
|
||||
google_compute_instance.test-gke.network_interface.0.network_ip
|
||||
)
|
||||
mysql = module.container-vm_cos-mysql.instances
|
||||
networking = map(
|
||||
google_compute_instance.test-net.name,
|
||||
google_compute_instance.test-net.network_interface.0.network_ip
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
output "mysql-root-password" {
|
||||
description = "Password for the test MySQL db root user."
|
||||
sensitive = true
|
||||
value = random_pet.mysql_password.id
|
||||
}
|
||||
131
infrastructure/shared-vpc/variables.tf
Normal file
131
infrastructure/shared-vpc/variables.tf
Normal file
@@ -0,0 +1,131 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
variable "billing_account_id" {
|
||||
description = "Billing account id used as default for new projects."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "kms_keyring_location" {
|
||||
description = "Location used for the KMS keyring."
|
||||
default = "europe"
|
||||
}
|
||||
|
||||
variable "kms_keyring_name" {
|
||||
description = "Name used for the KMS keyring."
|
||||
default = "svpc-example"
|
||||
}
|
||||
|
||||
variable "oslogin_admins_gce" {
|
||||
description = "GCE project oslogin admin members, in IAM format."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "oslogin_users_gce" {
|
||||
description = "GCE project oslogin user members, in IAM format."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "owners_gce" {
|
||||
description = "GCE project owners, in IAM format."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "owners_gke" {
|
||||
description = "GKE project owners, in IAM format."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "owners_host" {
|
||||
description = "Host project owners, in IAM format."
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "root_node" {
|
||||
description = "Hierarchy node where projects will be created, 'organizations/org_id' or 'folders/folder_id'."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "subnets" {
|
||||
description = "Shared VPC subnet definitions."
|
||||
default = [
|
||||
{
|
||||
subnet_name = "networking"
|
||||
subnet_ip = "10.0.0.0/24"
|
||||
subnet_region = "europe-west1"
|
||||
subnet_private_access = "true"
|
||||
},
|
||||
{
|
||||
subnet_name = "gce"
|
||||
subnet_ip = "10.0.16.0/24"
|
||||
subnet_region = "europe-west1"
|
||||
subnet_private_access = "true"
|
||||
},
|
||||
{
|
||||
subnet_name = "gke"
|
||||
subnet_ip = "10.0.32.0/24"
|
||||
subnet_region = "europe-west1"
|
||||
subnet_private_access = "true"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
variable "subnet_secondary_ranges" {
|
||||
description = "Shared VPC subnets secondary range definitions."
|
||||
default = {
|
||||
networking = [],
|
||||
gce = [],
|
||||
gke = [
|
||||
{
|
||||
range_name = "services"
|
||||
ip_cidr_range = "172.16.0.0/24"
|
||||
},
|
||||
{
|
||||
range_name = "pods"
|
||||
ip_cidr_range = "10.128.0.0/18"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
description = "Service APIs enabled by default in new projects."
|
||||
default = [
|
||||
"bigquery-json.googleapis.com",
|
||||
"bigquerystorage.googleapis.com",
|
||||
"cloudbilling.googleapis.com",
|
||||
"cloudkms.googleapis.com",
|
||||
"cloudresourcemanager.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"container.googleapis.com",
|
||||
"containerregistry.googleapis.com",
|
||||
"deploymentmanager.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iam.googleapis.com",
|
||||
"iamcredentials.googleapis.com",
|
||||
"logging.googleapis.com",
|
||||
"oslogin.googleapis.com",
|
||||
"pubsub.googleapis.com",
|
||||
"replicapool.googleapis.com",
|
||||
"replicapoolupdater.googleapis.com",
|
||||
"resourceviews.googleapis.com",
|
||||
"serviceusage.googleapis.com",
|
||||
"storage-api.googleapis.com",
|
||||
]
|
||||
}
|
||||
17
infrastructure/shared-vpc/versions.tf
Normal file
17
infrastructure/shared-vpc/versions.tf
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
terraform {
|
||||
required_version = ">= 0.12"
|
||||
}
|
||||
13
tests/infrastructure/__init__.py
Normal file
13
tests/infrastructure/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
13
tests/infrastructure/shared-vpc/__init__.py
Normal file
13
tests/infrastructure/shared-vpc/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
27
tests/infrastructure/shared-vpc/conftest.py
Normal file
27
tests/infrastructure/shared-vpc/conftest.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
"Plan fixture."
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
_TFDIR = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[-3:-1])
|
||||
|
||||
|
||||
@pytest.fixture(scope='package')
|
||||
def plan(plan):
|
||||
return plan(_TFDIR)
|
||||
4
tests/infrastructure/shared-vpc/terraform.tfvars
Normal file
4
tests/infrastructure/shared-vpc/terraform.tfvars
Normal file
@@ -0,0 +1,4 @@
|
||||
root_node = "folders/1234567890"
|
||||
prefix = "fabric-svpc"
|
||||
billing_account_id = "012345-012345-012345"
|
||||
owners_gce = ["user:user@example.com"]
|
||||
29
tests/infrastructure/shared-vpc/test_outputs.py
Normal file
29
tests/infrastructure/shared-vpc/test_outputs.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
"Test root module outputs."
|
||||
|
||||
|
||||
def test_vpc_ranges(plan):
|
||||
"VPC ranges should match input variables."
|
||||
ranges = plan.outputs['vpc_subnets']
|
||||
for subnet in plan.variables['subnets']:
|
||||
assert ranges[subnet['subnet_name']] == subnet['subnet_ip']
|
||||
|
||||
|
||||
def test_project_ids(plan):
|
||||
"Project ids should use prefix and match expected values."
|
||||
prefix = plan.variables['prefix']
|
||||
assert plan.outputs['host_project_id'] == prefix + '-vpc-host'
|
||||
assert plan.outputs['service_project_ids']['gce'] == prefix + '-gce'
|
||||
62
tests/infrastructure/shared-vpc/test_svpc_resources.py
Normal file
62
tests/infrastructure/shared-vpc/test_svpc_resources.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# Copyright 2019 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
|
||||
#
|
||||
# https://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.
|
||||
|
||||
"Test shared vpc resources in root module."
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def mod(plan):
|
||||
return plan.modules['module.net-svpc-access']
|
||||
|
||||
|
||||
def test_host_vpc(plan):
|
||||
"Test that the vpc project is set as shared vpc host."
|
||||
mod = plan.modules['module.net-vpc-host']
|
||||
resources = [v['values'] for v in mod.values() if v['type'] ==
|
||||
'google_compute_shared_vpc_host_project']
|
||||
assert resources[0]['project'] == plan.outputs['host_project_id']
|
||||
|
||||
|
||||
def test_service_projects(plan, mod):
|
||||
"Test that service projects are registered with the shared vpc."
|
||||
resources = [v['values'] for v in mod.values() if v['type'] ==
|
||||
'google_compute_shared_vpc_service_project']
|
||||
assert len(resources) == 2
|
||||
assert set([r['host_project'] for r in resources]) == set(
|
||||
[plan.outputs['host_project_id']])
|
||||
assert sorted([r['service_project'] for r in resources]) == sorted(
|
||||
plan.outputs['service_project_ids'].values())
|
||||
|
||||
|
||||
def test_subnet_users(plan, mod):
|
||||
"Test that the network user role is assigned on subnets."
|
||||
resources = [v['values'] for v in mod.values() if v['type'] ==
|
||||
'google_compute_subnetwork_iam_binding']
|
||||
assert len(resources) == 2
|
||||
assert set([r['project'] for r in resources]) == set(
|
||||
[plan.outputs['host_project_id']])
|
||||
assert sorted([r['subnetwork'] for r in resources]) == ['gce', 'gke']
|
||||
|
||||
|
||||
def test_service_agent(plan, mod):
|
||||
"Test that the service agent role is assigned for gke only."
|
||||
resources = [v['values'] for v in mod.values() if v['type'] ==
|
||||
'google_project_iam_binding']
|
||||
assert resources[0] == {
|
||||
'project': plan.outputs['host_project_id'],
|
||||
'role': 'roles/container.hostServiceAgentUser'
|
||||
}
|
||||
Reference in New Issue
Block a user