Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install yamllint
Expand Down
85 changes: 84 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,95 @@

Terraform module to create and manage Google Cloud Platform compute resources.

## Usage

See the [examples](examples) directory for working examples for reference:

```hcl
module "my_vpc" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git?ref=v0.1.0"
name = "my-vpc"
}
```

## Examples

- [minimal-network](examples/minimal-network) - Create a VPC with the minimum
configuration.
- [network-and-rules](examples/network-and-rules) - Create a VPC with
additional configuration to manage subnetworks and firewall rules.
- [virtual-machine](examples/virtual-machine) - Create a virtual machine.
- [kubernetes-cluster](examples/kubernetes-cluster) - Create a Kubernetes
cluster and separately managed node pool.

## Requirements

| Name | Version |
|------|---------|
| [terraform](https://www.terraform.io/) | >= 1.0 |

## Providers

| Name | Version |
|------|---------|
| [google](https://registry.terraform.io/providers/hashicorp/google/latest) | >= 4.71.0 |

## Modules

No modules.
- [`firewall_rules`](modules/firewall_rules) - Create and manage VPC firewall
rules.
- [`gce_instance`](modules/gce_instance) - Create and manage a virtual machines
instance.
- [`gke_cluster`](modules/gke_cluster) - Create and manage a Kubernetes cluster
where the node pool must be provisioned separately.
- [`gke_node_pool`](modules/gke_node_pool) - Create and manage a Kubernetes
node pool.

## Resources

| Name | Type |
|------|------|
| [`google_compute_global_address.private_ip_allocations[*]`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_global_address) | resource |
| [`google_compute_network.vpc`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource |
| [`google_compute_subnetwork.subnets[*]`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource |
| [`google_service_networking_connection.service_networking_connection`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_networking_connection) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| `name` | The name of the network, which must be unique within the project. The name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` | `string` | | yes |
| `auto_create_subnetworks` | Whether to create a subnetwork for each compute region automatically across the `10.128.0.0/9` address range | `bool` | `false` | no |
| `delete_default_routes_on_create` | Whether to delete the default routes (`0.0.0.0/0`) immediately after the network is created | `bool` | `false` | no |
| `description` | A description of the network | `string` | `null` | no |
| `mtu` | The maximum transmission unit (MTU) in bytes | `number` | `null` | no |
| `network_firewall_policy_enforcement_order` | The order that firewall rules and firewall policies are evaluated. Default value is `AFTER_CLASSIC_FIREWALL`. Possible values are: `AFTER_CLASSIC_FIREWALL`, `BEFORE_CLASSIC_FIREWALL` | `string` | `AFTER_CLASSIC_FIREWALL` | no |
| `private_service_connect_ranges` | A map of IP address blocks (CIDR notation) that are allowed to use Private Service Connect. If the address is not given in CIDR notation, then a prefix length of 16 is used | `map(string)` | `{}` | no |
| `project_id` | The ID of the project in which the resource belongs. If it is not provided, the provider project is used | `string` | `null` | no |
| `routing_mode` | The network-wide routing mode to use. If set to `REGIONAL`, this network's cloud routers will only advertise routes with subnetworks of this network in the same region as the router. If set to `GLOBAL`, this network's cloud routers will advertise routes with all subnetworks of this network, across regions. Possible values are: `GLOBAL`, `REGIONAL` | `string` | `REGIONAL` | no |
| `subnets` | Subnets to create in the network | `list(object{...})` | `[]` | no |
| `subnets[*].name` | The name of the resource, provided by the client when initially creating the resource. The name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash | `string` | | yes |
| `subnets[*].ip_cidr_range` | The range of internal addresses that are owned by this subnetwork. Provide this property when you create the subnetwork. For example, `10.0.0.0/8` or `192.168.0.0/16`. Ranges must be unique and non-overlapping within a network. Only IPv4 is supported | `string` | | yes |
| `subnets[*].description` | A description of the subnet | `string` | `null` | no |
| `subnets[*].log_config` | Denotes the logging options for the subnetwork flow logs. If logging is enabled logs will be exported to Stackdriver. This field cannot be set if the purpose of this subnetwork is `INTERNAL_HTTPS_LOAD_BALANCER` | `object{...}` | `null` | no |
| `subnets[*].log_config.aggregation_interval` | Toggles the aggregation interval for collecting flow logs. Default value is `INTERVAL_5_SEC`. Possible values are: `INTERVAL_5_SEC`, `INTERVAL_30_SEC`, `INTERVAL_1_MIN`, `INTERVAL_5_MIN`, `INTERVAL_10_MIN`, `INTERVAL_15_MIN` | `string` | `INTERVAL_5_SEC` | no |
| `subnets[*].log_config.filter_expr` | Export filter used to define which VPC flow logs should be logged, as as CEL expression. The default value is `true`, which evaluates to include everything | `string` | `true` | no |
| `subnets[*].log_config.flow_sampling` | The value of the field must be in [0, 1] | `number` | `0.5` | no |
| `subnets[*].log_config.metadata_fields` | Configures whether metadata fields should be added to the reported VPC flow logs. Default value is `INCLUDE_ALL_METADATA`. Possible values are: `EXCLUDE_ALL_METADATA`, `INCLUDE_ALL_METADATA`, `CUSTOM_METADATA` | `string` | `INCLUDE_ALL_METADATA` | no |
| `subnets[*].log_config.metadata` | List of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and `metadata` is set to `CUSTOM_METADATA` | `list(string)` | `[]` | no |
| `subnets[*].private_ip_google_access` | When enabled, virtual machines in this subnetwork without external IP addresses can access Google APIs and services by using Private Google Access | `bool` | `false` | no |
| `subnets[*].purpose` | The purpose of the resource. This field can be either `PRIVATE_RFC_1918`, `INTERNAL_HTTPS_LOAD_BALANCER` or `REGIONAL_MANAGED_PROXY`. Defaults to `PRIVATE_RFC_1918` | `string` | `PRIVATE_RFC_1918` | no |
| `subnets[*].region` | The GCP region for this subnetwork | `string` | `null` | no |
| `subnets[*].role` | The role of subnetwork. The value can be set to `ACTIVE` or `BACKUP`. An `ACTIVE` subnetwork is one that is currently being used. A `BACKUP` subnetwork is one that is ready to be promoted to `ACTIVE` or is currently draining. Subnetwork role must be specified when `purpose` is set to `INTERNAL_HTTPS_LOAD_BALANCER` or `REGIONAL_MANAGED_PROXY`. Possible values are: `ACTIVE`, `BACKUP` | `string` | `null` | no |
| `subnets[*].secondary_ip_ranges` | An array of configurations for secondary IP ranges for virtual machine instances contained in this subnetwork | `list(object{...})` | `[]` | no |
| `subnets[*].secondary_ip_ranges[*].ip_cidr_range` | The range of IP addresses belonging to this subnetwork secondary range. Provide this property when you create the subnetwork. Ranges must be unique and non-overlapping with all primary and secondary IP ranges within a network. Only IPv4 is supported | `string` | | yes |
| `subnets[*].secondary_ip_ranges[*].range_name` | The name associated with this subnetwork secondary range, used when adding an alias IP range to a VM instance. The name must be 1-63 characters long, and comply with RFC1035. The name must be unique within the subnetwork | `string` | | yes |
| `subnets[*].stack_type` | The stack type for this subnet to identify whether the IPv6 feature is enabled or not. If not specified `IPV4_ONLY` will be used. Possible values are: `IPV4_ONLY`, `IPV4_IPV6` | `string` | `IPV4_ONLY` | no |

## Outputs

| Name | Description |
|------|-------------|
| `id` | The network ID |
| `subnets` | The subnets in the network |
>>>>>>> 8558e3e (feat: add main compute networking module)
30 changes: 30 additions & 0 deletions examples/kubernetes-cluster/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
locals {
network = "my-vpc"
}

data "google_compute_network" "my_vpc" {
name = local.network
}

data "google_compute_subnetwork" "my_vpc_europe_west2" {
name = local.network
region = "europe-west2"
}

module "kubernetes_cluster" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git//modules/gke_cluster?ref = v0.1.0"
cluster_secondary_range_name = "gke-cluster-pods"
kubernetes_version = "1.24.12-gke.500"
location = data.google_compute_subnetwork.my_vpc_europe_west2.region
name = "my-cluster"
network = data.google_compute_network.my_vpc.id
services_secondary_range_name = "gke-cluster-services"
subnetwork = data.google_compute_subnetwork.my_vpc_europe_west2.id
}

module "kubernetes_cluster_node_pool_production" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git//modules/gke_node_pool?ref=v0.1.0"
cluster = module.kubernetes_cluster.name
location = module.kubernetes_cluster.location
pool_name = "my-pool"
}
1 change: 1 addition & 0 deletions examples/kubernetes-cluster/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provider "google" {}
9 changes: 9 additions & 0 deletions examples/kubernetes-cluster/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.71.0"
}
}
required_version = ">= 1.0"
}
4 changes: 4 additions & 0 deletions examples/minimal-network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module "my_vpc" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git?ref=v0.1.0"
name = "my-vpc"
}
1 change: 1 addition & 0 deletions examples/minimal-network/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provider "google" {}
9 changes: 9 additions & 0 deletions examples/minimal-network/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.71.0"
}
}
required_version = ">= 1.0"
}
77 changes: 77 additions & 0 deletions examples/network-and-rules/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
locals {
network_name = "my-vpc"
}

module "my_vpc" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git?ref=v0.1.0"
name = local.network_name

subnets = [
{
name = local.network_name
description = "VPC subnetwork in the Hong Kong region"
ip_cidr_range = "10.170.0.0/20"
region = "asia-east2"

log_config = {
aggregation_interval = "INTERVAL_10_MIN"
}
},
{
name = local.network_name
description = "VPC subnetwork in the London region"
ip_cidr_range = "10.154.0.0/20"
region = "europe-west2"

log_config = {
aggregation_interval = "INTERVAL_10_MIN"
}

secondary_ip_ranges = [
{
range_name = "gke-cluster-pods"
ip_cidr_range = "10.132.0.0/14"
},
{
range_name = "gke-cluster-services"
ip_cidr_range = "10.0.0.0/20"
},
]
},
]

private_service_connect_ranges = {
"servicenetworking-googleapis-com" : "10.124.0.0"
}
}

module "firewall_rules" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git//modules/firewall_rules?ref=v0.1.0"
network = module.my_vpc.name

# Allow HTTP, HTTPS, and SSH from anywhere.
default_rules = {
http_ranges = ["0.0.0.0/0"]
https_ranges = ["0.0.0.0/0"]
ssh_ranges = ["0.0.0.0/0"]
}

egress_rules = {
"my-vpc-deny-smtp" = {
ports = ["25"]
source_ranges = ["10.170.0.0/20"]
}
}

ingress_rules = {
"my-vpc-allow-ftp" = {
allow = true
ports = ["21"]
target_tags = ["ftp-server"]
}
"my-vpc-deny-remote-desktop" = {
ports = ["3389"]
destination_ranges = ["0.0.0.0/0"]
}
}
}
1 change: 1 addition & 0 deletions examples/network-and-rules/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provider "google" {}
9 changes: 9 additions & 0 deletions examples/network-and-rules/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.71.0"
}
}
required_version = ">= 1.0"
}
30 changes: 30 additions & 0 deletions examples/virtual-machine/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
data "google_compute_image" "instance_image" {
name = "ubuntu-1804-bionic-v20200414"
}

data "google_compute_subnetwork" "europe_west2" {
name = "default"
region = "europe-west2"
}

module "instance" {
source = "git::https://github.com/kapetndev/terraform-google-compute.git//modules/gce_instance?ref=v0.1.0"
hostname = "app.c.my-project.internal"
name = "my-instance"
zone = "europe-west2-a"

boot_disk = {
initialize_params = {
image = data.google_compute_image.instance_image.self_link
}
}

network_interfaces = [
{ subnetwork = data.google_compute_subnetwork.europe_west2.self_link },
]

tags = [
"https-server",
"ssh-server",
]
}
1 change: 1 addition & 0 deletions examples/virtual-machine/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
provider "google" {}
9 changes: 9 additions & 0 deletions examples/virtual-machine/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.71.0"
}
}
required_version = ">= 1.0"
}
10 changes: 10 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "google_compute_network" "network" {
auto_create_subnetworks = var.auto_create_subnetworks
delete_default_routes_on_create = var.delete_default_routes_on_create
description = var.description
mtu = var.mtu
name = var.name
network_firewall_policy_enforcement_order = var.network_firewall_policy_enforcement_order
project = var.project_id
routing_mode = var.routing_mode
}
34 changes: 34 additions & 0 deletions modules/firewall_rules/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DEFAULT_GOAL := validate
.DELETE_ON_ERROR:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
TERRAFORM := terraform

ifeq ($(origin .RECIPEPREFIX), undefined)
$(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
endif
.RECIPEPREFIX =

.PHONY: help
help:
@echo "Usage: make <target>"
@echo
@echo "Targets:"
@echo " init Initialize the Terraform working directory"
@echo " validate Validate the configuration"
@echo " clean Clean the Terraform working directory"

.PHONY: init
init:
$(TERRAFORM) init -backend=false

.PHONY: validate
validate: init
$(TERRAFORM) validate

.PHONY: clean
clean:
@rm -rf .terraform
Loading