linode / terraform-provider-linode

Terraform Linode provider
https://www.terraform.io/docs/providers/linode/
Mozilla Public License 2.0
197 stars 94 forks source link

[Feature]: Get the `linode_nodebalancer` & `linode_nodebalancer_config` ID by a label query. #944

Closed raisedadead closed 7 months ago

raisedadead commented 1 year ago

Description

The data resource for NodeBalancer and NodeBalancer Config is tedious to manage:

data "linode_nodebalancer" "example_nb_pxy" {
  id = XXXXXX
}

data "linode_nodebalancer_config" "example_nb_pxy_config__port_443" {
  id              = YYYYYY
  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
}

data "linode_nodebalancer_config" "example_nb_pxy_config__port_80" {
  id              = ZZZZZZ
  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
}

The IDs: XXXXXX, YYYYYY, and ZZZZZZ are resource IDs that we need to find using either the Linode CLI, Linode API, or some other method before using it in the code above. This is less than ideal.

Please include a query by label OR tags to better manage this.

New or Affected Terraform Resources

linode_nodebalancer linode_nodebalancer_config

Potential Terraform Configuration

data "linode_nodebalancer" "example_nb_pxy" {
  filter {
    name = "label"
    values = ["my-label", "my-other-label"]
  }

  filter {
    name = "tags"
    values = ["my-tag"]
  }
}

data "linode_nodebalancer_config" "example_nb_pxy_config__port_443" {
  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
  filter {
    name = "label"
    values = ["my-label", "my-other-label"]
  }

  filter {
    name = "tags"
    values = ["my-tag"]
  }
}

data "linode_nodebalancer_config" "example_nb_pxy_config__port_80" {
  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
  filter {
    name = "label"
    values = ["my-label", "my-other-label"]
  }

  filter {
    name = "tags"
    values = ["my-tag"]
  }
}

resource "linode_nodebalancer_node" "example_nb_pxy_nodes__port_443" {
  count = local.pxy_node_count

  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
  config_id       = data.linode_nodebalancer_config.example_nb_pxy_config__port_443.id
  address         = "${linode_instance.example_pxy[count.index].private_ip_address}:443"
  label           = "example-node-pxy-443-${count.index}"
}

resource "linode_nodebalancer_node" "example_nb_pxy_nodes__port_80" {
  count = local.pxy_node_count

  nodebalancer_id = data.linode_nodebalancer.example_nb_pxy.id
  config_id       = data.linode_nodebalancer_config.example_nb_pxy_config__port_80.id
  address         = "${linode_instance.example_pxy[count.index].private_ip_address}:80"
  label           = "example-node-pxy-80-${count.index}"
}
jcallahan-akamai commented 1 year ago

@raisedadead thanks for opening this issue.

We are looking to add a NodeBalancers data source which will allow you to filter by label and tag as you've described. WIP PR for reference.

Achieving what you want for NodeBalancer Configs is more complex, but we are looking into this as well.

jcallahan-akamai commented 1 year ago

Alternatively – @raisedadead in your "Potential Terraform Configuration" you are using the linode_nodebalancer_node resources, but not the linode_nodebalancer or linode_nodebalancer_config resources.

Can you manage your NodeBalancers and NB Configs via Terraform as well? Then you wouldn't need to use data sources; you could reference the resource itself. Something like this:

resource "linode_nodebalancer" "example_nb_proxy" {
  label  = "my-label"
  region = "us-east"
}

resource "linode_nodebalancer_config" "example_nb_pxy_config__port_80" {
  port            = 80
  nodebalancer_id = linode_nodebalancer.example_nb_proxy.id
  protocol        = "http"
  algorithm       = "roundrobin"
  stickiness      = "none"
  check           = "http_body"
  check_interval  = "90"
  check_timeout   = "10"
  check_attempts  = "3"
  check_path      = "/test/"
  check_body      = "it works"
  check_passive   = true
}

resource "linode_nodebalancer_node" "example_nb_pxy_nodes__port_80" {
  count           = local.pxy_node_count
  nodebalancer_id = linode_nodebalancer.example_nb_proxy.id
  config_id       = linode_nodebalancer_config.example_nb_pxy_config__port_80.id
  address         = "${linode_instance.example_pxy[count.index].private_ip_address}:80"
  label           = "example-node-pxy-80-${count.index}"
}

Are more complete example can be found here.

raisedadead commented 1 year ago

Hi @jcallahan-akamai

Thanks for your response. I'm looking at your PR, which should solve our needs.

Achieving what you want for NodeBalancer Configs is more complex, but we are looking into this as well.

If it helps, it should be fine if we could query the configs from the NB data source as an attribute. The main thing is to find the NB data source.

Can you manage your NodeBalancers and NB Configs via Terraform as well?

We do, actually!

Unfortunately, we must keep the NB Terraform configs separate from the nodes for the business logic.

For context, the NBs will almost never change. They are our primary origins and entry points. The idea is to swap out nodes (via separate TF Configs) for a blue-green-style deployment.

We avoid accidental changes by keeping them separate (and using NBs as data sources).

We are fine with the "hardcoding" right now - it gets the job done and will update the code whenever the PR makes the cut.

Thanks again.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

raisedadead commented 1 year ago

Hi @jcallahan-akamai @lgarber-akamai - Do you want to keep this open? We would still want this. Is there anything we can do to help?

zliang-akamai commented 1 year ago

Hi @raisedadead, The PR (https://github.com/linode/terraform-provider-linode/pull/955) by @jcallahan-akamai has been merged and released in version v2.6.0. Can you try to upgrade the Linode Terraform Provider and let us know the result?

raisedadead commented 1 year ago

So - I gave this a cursory look, and it seems that the data source for linode_nodebalancers has been added and will suffice first part of our needs. That is I believe we can now:

data "linode_nodebalancers" "example_nbs" {
  filter {
    name   = "label"
    values = ["example-nb"]
  }
}

data "linode_nodebalancer_config" "example_nb_config" {
  id              = 999999 # TODO: Find a way to get this ID dynamically
  nodebalancer_id = data.linode_nodebalancers.example_nbs.nodebalancers[0].id
}

We would still want a data source to filter on linode_nodebalancer_configs, too, and from John's comments, it is more involving and may be in the works.

Consider splitting this into a separate issue if you like for filtering on the configs.

jcallahan-akamai commented 1 year ago

Hey @raisedadead, we've added a task to create a filterable linode_nodebalancer_configs datasource to our backlog. We'll keep this issue open until we can work on it.

yec-akamai commented 8 months ago

Hi @raisedadead, yesterday we released a new version v2.12.0 which supports filtering on linode_nodebalancer_configs. Please let us know if it works for your and reach out for any issue!

raisedadead commented 8 months ago

Sure - let me get back to you all after we upgrade our code to use this version. Thanks a lot!

raisedadead commented 7 months ago

We have been using this, and works like a charm. Thanks getting these out!