1
votes

terraform has adjusted its authorization

in main.tf [for sql config] I now have:

resource "google_sql_database_instance" "master" {
  name             = "${random_id.id.hex}-master"
  region           = "${var.region}"
  database_version = "POSTGRES_9_6"

# allow direct access from work machines 
  ip_configuration {
    authorized_networks = "${var.authorized_networks}"
    require_ssl  = "${var.sql_require_ssl}"
    ipv4_enabled = true
  }
}

where

in variables.tf I have

variable "authorized_networks" {
  description = "The networks that can connect to cloudsql"
  type        = "list"

  default = [
    {
      name  = "work"
      value = "xxx.xxx.xx.xxx/32"
    }
  ]
}

where xxx.xxx.xx.xxx is the ip address I would like to allow. However, I prefer not to put this in my variables.tf file, but rather in a non-source controlled .tfvars file.

for variables that have a simple value, this is easy, but it is not clear to me how to do it with the nested structure. Replacing xxx.xxx.xx.xxx by a variable [e.g. var.work_ip] leads to an error

variables may not be used here

any insights?

1
Can you edit your question to make it an minimal reproducible example that is runnable? It's not 100% clear from this much more stripped down context what you're trying to achieve or the limitations.ydaetskcoR
Have you seen this issue? The thread seems to have a few potential workarounds in it, possibly using null resources. Haven't used them myself, so can't offer further insight...James Thorpe

1 Answers

0
votes

If you omit the default argument in your main configuration altogether, you will mark variable "authorized_networks" as a required input variable, which Terraform will then check to ensure that it is set by the caller.

If this is a root module variable, then you can provide the value for it in a .tfvars file using the following syntax:

authorized_networks = [
  {
    name  = "work"
    value = "xxx.xxx.xx.xxx/32"
  }
]

If this file is being generated programmatically by some wrapping automation around Terraform, you can also write it into a .tfvars.json file and use JSON syntax, which is often easier to construct robustly in other languages:

{
  "authorized_networks": [
    {
      "name": "work",
      "value": "xxx.xxx.xx.xxx/32"
    }
  ]
}

You can either specify this file explicitly on the command line using the -var-file option, or you can give it a name ending in .auto.tfvars or .auto.tfvars.json in the current working directory when you run Terraform and Terraform will then find and load it automatically.


A common reason to keep something out of version control is because it's a dynamic setting configured elsewhere in the broader system rather than a value fixed in version control. If that is true here, then an alternative strategy is to save that setting in a configuration data store that Terraform is able to access via data sources and then write your Terraform configuration to retrieve that setting directly from the place where it is published.

For example, if the network you are modelling here were a Google Cloud Platform subnetwork, and it has either a fixed name or one that can be derived systematically in Terraform, you could retrieve this setting using the google_compute_subnetwork data source:

data "google_compute_subnetwork" "work" {
  name   = "work"
}

Elsewhere in configuration, you can then use data.google_compute_subnetwork.work.ip_cidr_range to access the CIDR block definition for this network.

The major Terraform providers have a wide variety of data sources like this, including ones that retrieve specific first-class objects from the target platform and also more generic ones that access configuration stores like AWS Systems Manager Parameter Store or HashiCorp Consul. Accessing the necessary information directly or publishing it "online" in a configuration store can be helpful in a larger system to efficiently integrate subsystems.