hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.31k stars 1.73k forks source link

Changing source_ranges to source_service_accounts does not remove source_ranges #16221

Open d-costa opened 11 months ago

d-costa commented 11 months ago

Community Note

Terraform Version

Terraform v1.6.1
on linux_amd64
+ provider registry.terraform.io/hashicorp/google v5.1.0

Affected Resource(s)

Terraform Configuration Files

First configuration:

terraform {
  required_version = "1.6.1"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.1.0"
    }
  }
}

provider "google" {
  project = var.project_id
}

variable "project_id" {
  type = string
}

resource "google_compute_network" "this" {
  name                    = "test-vpc"
  auto_create_subnetworks = true
}

resource "google_compute_firewall" "default" {
  name    = "allow-http"
  network = google_compute_network.this.id

  allow {
    protocol = "tcp"
    ports    = ["80"]
  }

  source_ranges = ["10.0.0.0/24"]
}

resource "google_service_account" "this" {
  account_id = "test-sa"
}

Second configuration:

terraform {
  required_version = "1.6.1"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.1.0"
    }
  }
}

provider "google" {
  project = var.project_id
}

variable "project_id" {
  type = string
}

resource "google_compute_network" "this" {
  name                    = "test-vpc"
  auto_create_subnetworks = true
}

resource "google_compute_firewall" "default" {
  name    = "allow-http"
  network = google_compute_network.this.id

  allow {
    protocol = "tcp"
    ports    = ["80"]
  }

  source_service_accounts = [google_service_account.this.email]
}

resource "google_service_account" "this" {
  account_id = "test-sa"
}

Debug Output

Panic Output

Expected Behavior

Actual Behavior

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # google_compute_firewall.default will be updated in-place
  ~ resource "google_compute_firewall" "default" {
        id                      = "projects/PROJECT_ID/global/firewalls/allow-http"
        name                    = "allow-http"
      ~ source_ranges           = [
          - "10.0.0.0/24",
        ]
        # (12 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_firewall.default: Modifying... [id=projects/PROJECT_ID/global/firewalls/allow-http]
google_compute_firewall.default: Still modifying... [id=projects/PROJECT_ID/global/firewalls/allow-http, 10s elapsed]
google_compute_firewall.default: Modifications complete after 12s [id=projects/PROJECT_ID/global/firewalls/allow-http]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Steps to Reproduce

  1. terraform apply the first config
  2. terraform apply the second config
  3. Observe that the resource still has the source_range as source filter

Important Factoids

References

b/304967568

eahrend commented 9 months ago

I tested this out with source tags as well, we need to manually edit the firewall rule after its created to change the source filter.

We're using CDKTF, but it's still TF under the hood, our code looks like:


type ComputeFirewallRule struct {
    Protocol string
    Ports    []string
}

type ComputeFirewall struct {
    Name         string
    Network      string
    Allow        []ComputeFirewallRule
    SourceTags   []string 
    TargetTags   []string 
    SourceRanges []string 
    Priority     int      
    Direction    string  
}

const GCPFIREWALLINGRESS = "INGRESS"
const GCPFIREWALLEGRESS = "EGRESS"

func CreateComputeFirewall(s cdktf.TerraformStack, f ComputeFirewall, projectId *string) {
    var allow []ComputeFirewallAllow

    for _, r := range f.Allow {
        allow = append(allow, cf.ComputeFirewallAllow{
            Protocol: jsii.String(r.Protocol),
            Ports:    jsii.Strings(r.Ports...),
        })
    }
    computeFirewallconfig := &cf.ComputeFirewallConfig{
        Name:    &f.Name,
        Network: &f.Network,
        Allow:   allow,
        Project: projectId,
    }
    if len(f.SourceRanges) > 0 {
        computeFirewallconfig.SourceRanges = jsii.Strings(f.SourceRanges...)
    }
    if len(f.TargetTags) > 0 {
        computeFirewallconfig.TargetTags = jsii.Strings(f.TargetTags...)
    }
    if len(f.SourceTags) > 0 {
        computeFirewallconfig.SourceTags = jsii.Strings(f.SourceTags...)
    }
    cf.NewComputeFirewall(s, &f.Name, computeFirewallconfig)
}

Even on a brand new firewall rule, it sets the source_ranges to 0.0.0.0/0