Operate GCP VM Firewall Rules (HyOps)¶
-
Purpose: Manage named GCP ingress firewall rules scoped to VM network tags, independently of shared VPC infrastructure. Owner: Platform engineering
-
Trigger: New VM deployment needs port access (RDP, VNC, app ports, standalone IAP SSH), or rule cleanup after VM teardown
- Impact: Creates or removes
google_compute_firewallresources on the target VPC -
Severity: P3 Pre-reqs: GCP init complete for the environment, target VPC exists,
platform/gcp/platform-vmstate exists if tagging VMs. -
Rollback strategy: Run
hyops destroywith the same module ref and inputs file.
Context¶
Module: platform/gcp/vm-firewall-rules
Driver: iac/terragrunt
Pack: gcp/platform/10-platform/10-vm-firewall-rules@v1.0
This module manages firewall rules that are scoped to specific VMs via network tags. It does not touch the VPC, subnets, or any shared network infrastructure. It is the correct tool when:
- You need a port opened for a specific VM type (e.g., RDP on
allow-rdptag) - You are using the default VPC or a VPC not managed by
org/gcp/wan-hub-network - You need the IAP SSH rule on a standalone VPC (rather than depending on wan-hub-network)
For VMs already on a VPC managed by org/gcp/wan-hub-network, the IAP SSH rule already exists and this module is not needed for port 22.
Inputs reference¶
| Input | Type | Default | Notes |
|---|---|---|---|
name_prefix |
string | "" |
Used in firewall rule name: {prefix}-{context_id}-{name_suffix} |
context_id |
string | "" |
Scoping identifier |
project_id |
string | "" |
Optional override; defaults to env credentials project |
network |
string | "default" |
VPC network name |
rules |
list | [] |
List of rule objects (see below) |
Each rule in rules:
| Field | Required | Default | Notes |
|---|---|---|---|
name_suffix |
yes | : | Appended to prefix to form the GCP rule name |
description |
no | "" |
|
direction |
no | INGRESS |
INGRESS or EGRESS |
priority |
no | 1000 |
|
source_ranges |
no | [] |
CIDR ranges (INGRESS); becomes destination_ranges for EGRESS |
target_tags |
no | [] |
Network tags the rule applies to |
allow |
yes | : | List of {protocol, ports[]} |
Common patterns¶
RDP access for a Windows VM¶
name_prefix: platform
context_id: desktop
network: default
rules:
- name_suffix: allow-rdp
description: "RDP access for Windows desktop VM"
direction: INGRESS
priority: 1000
source_ranges:
- "<YOUR_IP>/32"
target_tags:
- allow-rdp
allow:
- protocol: tcp
ports: ["3389"]
The corresponding VM must carry the allow-rdp tag in its platform/gcp/platform-vm inputs.
IAP SSH on default VPC (standalone: no wan-hub-network)¶
name_prefix: platform
context_id: labs
network: default
rules:
- name_suffix: allow-iap-ssh
description: "IAP SSH access for platform VMs"
direction: INGRESS
priority: 1000
source_ranges:
- "35.235.240.0/20"
target_tags:
- allow-iap-ssh
allow:
- protocol: tcp
ports: ["22"]
Multiple rules in one module state¶
name_prefix: platform
context_id: desktop
network: default
rules:
- name_suffix: allow-rdp
source_ranges: ["<YOUR_IP>/32"]
target_tags: [allow-rdp]
allow:
- protocol: tcp
ports: ["3389"]
- name_suffix: allow-iap-ssh
source_ranges: ["35.235.240.0/20"]
target_tags: [allow-iap-ssh]
allow:
- protocol: tcp
ports: ["22"]
Steps¶
-
Prepare inputs file
cp "$HYOPS_CORE_ROOT/modules/platform/gcp/vm-firewall-rules/examples/inputs.min.yml" \ ~/my-firewall-rules.yml # edit to set name_prefix, context_id, network, and rules -
Preflight
hyops preflight --env dev \ --module platform/gcp/vm-firewall-rules \ --inputs ~/my-firewall-rules.yml -
Apply
hyops apply --env dev \ --module platform/gcp/vm-firewall-rules \ --inputs ~/my-firewall-rules.yml -
Verify
hyops state show --env dev --module platform/gcp/vm-firewall-rules
Expected: status: ok, outputs.rule_names map populated.
Cross-check in GCP:
gcloud compute firewall-rules list \
--project <PROJECT_ID> \
--filter="targetTags~allow-rdp OR targetTags~allow-iap-ssh" \
--format="table(name,network,direction,sourceRanges,targetTags,allowed)"
- Destroy (when VMs are torn down)
hyops destroy --env dev \ --module platform/gcp/vm-firewall-rules \ --inputs ~/my-firewall-rules.yml
Verification¶
Primary state:
~/.hybridops/envs/<env>/state/modules/platform__gcp__vm-firewall-rules/latest.json
Run-record files:
~/.hybridops/envs/<env>/logs/module/platform__gcp__vm-firewall-rules/<run_id>/
├── terragrunt_apply.stdout.txt
├── terragrunt_destroy.stdout.txt
└── driver_result.json
Updating source ranges¶
To restrict or expand which IPs can reach the VM, edit the source_ranges in your inputs file and re-apply. Terraform will update the rule in place:
hyops apply --env dev \
--module platform/gcp/vm-firewall-rules \
--inputs ~/my-firewall-rules.yml
Troubleshooting¶
already exists error during apply¶
Cause: a firewall rule with the same computed name exists outside Terraform state (created manually or by another module).
Fix:
- Rename the
name_suffixin your inputs, or - Import the existing rule into Terraform state (advanced: requires direct
terraform importvia the pack directory)
Rule exists but VM is still unreachable¶
Check (in order):
-
VM has the matching network tag:
gcloud compute instances describe <VM_NAME> \ --project <PROJECT_ID> --zone <ZONE> \ --format="get(tags.items)" -
Rule targets the correct network (not a different VPC)
- Source IP matches
source_ranges(check your current public IP) - The destination port is actually listening on the VM
source_ranges must not be empty for INGRESS¶
Cause: source_ranges left as [] in the inputs for an INGRESS rule.
Fix: provide at least one CIDR range. For IAP SSH use 35.235.240.0/20. For RDP use your operator IP.