DimensionDataResearch / terraform-provider-ddcloud

Terraform provider for Dimension Data cloud compute.
MIT License
16 stars 13 forks source link

ddcloud_anti_affinity resource type #100

Closed mike-nagy closed 6 years ago

mike-nagy commented 6 years ago

I am having a bit of trouble with the ddcloud_anti_affinity resource type. Please forgive me if my questions seem elementary but I am hoping you could point me in the right direction with my script. I have read through the documentation on GitHub and it is not clear to me how to reference the servers to include in the rule. Below is a sample of my code, would you be able to provide some advice on what I may be doing wrong. In my test I am creating 2 servers and then want to put them into an anti-affinity rule. Thank you in advance for any information you can provide

resource "ddcloud_server" "gis_server" {
  count                = "${var.server_count}"
  name                 = "${var.servername}_${count.index}"
  description          = "My Terraform test server."
  admin_password       = "P@ssw0rd1"

  memory_gb            = 8
  cpu_count            = 2
  cpu_speed            = "STANDARD"
  cores_per_cpu        = 1

  image                = "Windows2016 Std 2 CPU"
  auto_start           = "true"

  networkdomain        = "${ddcloud_networkdomain.gis_network_domain.id}"

  primary_network_adapter {
    vlan               = "${ddcloud_vlan.gis_mgmt_vlan.id}"
  }
  disk {
    scsi_unit_id     = 0
    size_gb          = 50
    speed            = "STANDARD"
  }

}

resource "ddcloud_server_anti_affinity" "gis_test_anti_affinity_rule" {
    server1 = "${ddcloud_server.gis_server.0}"
    server2 = "${ddcloud_server.gis_server.1}"
}
wninobla commented 6 years ago

The resource for "ddcloud_server_anti_affinity" requires a rule for setting the dependency on the server objects being available before it can be referenced. Assuming the other portions work (e.g. spinning up a network domain, spinning up the VLAN and then building the servers) that's all you should need. Else, you will need to set the dependencies for the other items as well.

I'd recommend if you haven't already confirmed doing so ripping out each piece and ensuring things build out in order which should help you troubleshoot this all.

tintoy commented 6 years ago

Hi - the trick is to use the * character like so:

https://github.com/DimensionDataResearch/daas-demo/blob/9bef250cfaa65c092576a0ee997707c247ac31bc/deploy/terraform/ddcloud/kube-hosts.tf#L59

tintoy commented 6 years ago

Essentially, putting .*. in an expression evaluates as an array of values (which you then use the element function to extract the required value from). The trick is to use the count property on the ddcloud_server_anti_affinity resource so that there is one for each ddcloud_server and then use count.index to match them up.

(sorry for the delayed reply - I'm at a conference today)

tintoy commented 6 years ago

More info in the Terraform docs here, here, and here. You could also use .0. and .1. but .*. with count.index is much cleaner :)

calloes commented 6 years ago

I use this in a different resource but ultimately iterates through each element the resource is based on and as above put the count in the resource

host = "${element(ddcloud_server.mysql_server.*.primary_network_adapter.0.ipv6, count.index)}"

wninobla commented 6 years ago

All good comments there. =) So, you should be all set between setting the * as well as ensuring the object exists first so it can be referenced in the code as it will need that all handy before it can iterate through. Else, it'll be a blank value and error out.

It will help if you have logs also so if you can send those out if you still have problems that will help pinpoint where it fails.

tintoy commented 6 years ago

Terraform should do that for you normally, it infers dependencies from expression references.

calloes commented 6 years ago

You must have .id on the end by the way to reference the resource itself this works on one of my environments

resource "ddcloud_server_anti_affinity" "mysql_anti_affinity_rule" {
    #count   = 2
    server1 = "${ ddcloud_server.mysql_server.0.id }"
    server2 = "${ ddcloud_server.mysql_server.1.id }"
}
mike-nagy commented 6 years ago

Thats the piece that was missing for me, adjusting my reference from

server1 = "${ ddcloud_server.mysql_server.0 }"

to

server1 = "${ ddcloud_server.mysql_server.0.id }"

and now it works for me thank you all for the feedback.

tintoy commented 6 years ago

@mike-nagy - I'm going to close this issue now, since it sounds like it's been resolved, but feel free to reopen if you still have further questions.