Community

issues with the terraform provider

Hi, I´ve got some issues with the a terraform script. I create a datacenter, two lans and two servers. Both servers are connected to a private lan (lan2) and one of the servers is connected to the public lan as well.

resource "profitbricks_datacenter" "main" {
  name = "xx_test"
  location = "de/fra"
  description = "Cusomer Data Center"
}

//Public Lan
resource "profitbricks_lan" "lan1" {
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = true
}

//Private Lan
resource "profitbricks_lan" "lan2" {
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = false
}

resource "profitbricks_server" "salt-master" {
  name = "salt-master"
  datacenter_id = "${profitbricks_datacenter.main.id}"
  cores = 1
  ram = 2048
  availability_zone = "AUTO"
  cpu_family = "AMD_OPTERON"
  volume {
    name = "system"
    image_name = "${var.ubuntu}"
    size = 30
    disk_type = "HDD"
    ssh_key_path = ["${var.public_key_path}"]    
    image_password = "XXXXXXXX"
  }
  nic {
    lan = "${profitbricks_lan.lan1.id}"
    dhcp = true
    firewall_active = true
    firewall {
      protocol = "TCP"
      name = "SSH"
      port_range_start = 22
      port_range_end = 22
    }
  }
  provisioner "remote-exec" {
    inline = [
      # install salt-master
      "curl -L https://bootstrap.saltstack.com -o install_salt.sh",
      "sudo sh install_salt.sh -M",
    ]
    connection {
      type = "ssh"
      private_key = "${file("${var.private_key_path}")}"
      user = "root"
      timeout = "4m"
    }
  }
}

resource "profitbricks_server" "salt-minion" {
  name = "salt-minion"
  datacenter_id = "${profitbricks_datacenter.main.id}"
  cores = 1
  ram = 2048
  availability_zone = "AUTO"
  cpu_family = "AMD_OPTERON"
  volume {
    name = "system"
    image_name = "${var.ubuntu}"
    size = 30
    disk_type = "HDD"
    ssh_key_path = ["${var.public_key_path}"]    
    image_password = "XXXXXXXX"
  }
  nic {
    lan = "${profitbricks_lan.lan2.id}"
    dhcp = true
  }
  provisioner "remote-exec" {
    inline = [
      # install salt-master
      "curl -L https://bootstrap.saltstack.com -o install_salt.sh",
      "sudo sh install_salt.sh",
    ]
    connection {
      type = "ssh"
      private_key = "${file("${var.private_key_path}")}"
      user = "root"
      timeout = "4m"
    }
  }
}

resource "profitbricks_nic" "master_nic" {
  datacenter_id   = "${profitbricks_datacenter.main.id}"
  server_id       = "${profitbricks_server.salt-master.id}"
  lan             = "${profitbricks_lan.lan2.id}"
  dhcp            = true
}

Wenn I start the script for the first time, it works fine until the creation of the second server. I get the error:

Error applying plan:

2 error(s) occurred:

* profitbricks_server.salt-minion: Resource 'profitbricks_lan.lan2' does not have attribute 'id' for variable 'profitbricks_lan.lan2.id'
* profitbricks_nic.master_nic: Resource 'profitbricks_lan.lan2' does not have attribute 'id' for variable 'profitbricks_lan.lan2.id'

But the output said:

profitbricks_lan.lan2: Creation complete
profitbricks_lan.lan1: Creation complete (ID: 2)

Starting the script again without deleting the datacenter: The second run creates lan2 (again?) now with an id

profitbricks_lan.lan2: Creation complete (ID: 3)

The secons server is created as well, but the remote_exec provisioner is not able to connect to the server, After a lot of tries

profitbricks_server.salt-minion (remote-exec):   Host: 10.14.106.12
profitbricks_server.salt-minion (remote-exec):   User: root
profitbricks_server.salt-minion (remote-exec):   Password: true
profitbricks_server.salt-minion (remote-exec):   Private key: true
profitbricks_server.salt-minion (remote-exec):   SSH Agent: false

I get:

profitbricks_server.salt-minion: Still creating... (6m10s elapsed)

Error applying plan:

1 error(s) occurred:

* profitbricks_server.salt-minion: 1 error(s) occurred:

* timeout

Could you provide any hint? Cheers, Uli

BTW: How can I get the IP-Address of the first server (salt-master) in the private lan, when I create the secons one? Assmne some ${profitbricks_server.salt-master.xxx}

 
  • **bold**
  • _italics_
  • `code`
  • ```code block```
  • # Heading 1
  • ## Heading 2
  • > Quote
 

Took a long time to test for me, but seems to work now. Thanks

Hello Uli,

I've looked into this a bit and I'm not quite sure how to resolve the issue you are reporting. I'm curious, did you happen to try running this with the -parallelism=1 option, like .\terraform.exe apply -parallelism=1 option to see if it makes any difference for you?

Based on the error messages you supplied, it seems like there is some sort of issue with the creation of the two LANs. I'm not exactly sure what that issue is just yet, but I will see what I can find out.

Eric

Uli,

While the -parallelism=1 option mentioned above may work, there is another way of doing something similar that should end up being faster. Terraform has a configuration meta-parameter called depends_on which is described on the Terraform Resources Page.

Since the issue seems to be with the provisioning of the two LANs, where one reports back as "complete" before it has an ID assigned, I tried setting the second LAN to depend on the first LAN, like this:

//Public Lan
resource "profitbricks_lan" "lan1" {
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = true
  name = "LAN1Public"
}

//Private Lan
resource "profitbricks_lan" "lan2" {
  depends_on = ["profitbricks_lan.lan1"]
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = false
  name = "LAN2Private"
}

When I ran terraform apply, this was in the output:

profitbricks_lan.lan1: Creating...
  datacenter_id: "" => "4cf45402-b29b-4fb7-9b66-4b868e216700"
  name:          "" => "LAN1Public"
  public:        "" => "true"
profitbricks_lan.lan1: Still creating... (10s elapsed)
profitbricks_lan.lan1: Creation complete (ID: 1)
profitbricks_lan.lan2: Creating...
  datacenter_id: "" => "4cf45402-b29b-4fb7-9b66-4b868e216700"
  name:          "" => "LAN2Private"
  public:        "" => "false"
profitbricks_lan.lan2: Still creating... (10s elapsed)
profitbricks_lan.lan2: Creation complete (ID: 2)

So, both LANs were created and assigned an ID.

While it may not have been necessary, I added a:

depends_on = ["profitbricks_lan.lan1","profitbricks_lan.lan2"]

to both the salt-master and salt-minion sections of the config file.

And just out of an abundance of caution, I added a depends_on to the the extra NIC for salt-master:

resource "profitbricks_nic" "master_nic" {
  depends_on = ["profitbricks_server.salt-master"]

Once those were in place, everything successfully built in around 4 minutes. Mind you, I had removed the code for bootstrapping salt, so it was just provisioning the Ubuntu OS, and adding the extra NIC to salt-master.

Oh, one final note, you should give your volumes a unique name. They are both named "system" in the config example. It will build, but later the DCD will probably complain about it and want you to resolve the "issue".

Hopefully this suggestion will get things moving in a positive direction for you. I will see what we can do to isolate and resolve the root cause of the LAN reporting back as "complete" before it actually has an ID assigned when multiple LANs are being provisioned simultaneously.

Eric

Hi Eric, the depends_on linking seems to work for me. Many Thanks, Uli

Hi Eric, setting the name of a lan seems not to work. Cheery, Uli

Hi Uli,

I'm not sure exactly where you are seeing the "name of a lan seems not to work". If I have this in the .tf file:

resource "profitbricks_datacenter" "main" {
  name = "TFTest3"
  location = "us/ewr"
  description = "TF Test DC2"
}

//Public Lan
resource "profitbricks_lan" "lan1" {
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = true
  name = "LAN1Public"
}

//Private Lan
resource "profitbricks_lan" "lan2" {
  depends_on = ["profitbricks_lan.lan1"]
  datacenter_id = "${profitbricks_datacenter.main.id}"
  public = false
  name = "LAN2Private"
}

It runs successfully and shows me:

profitbricks_datacenter.main: Creating...
  description: "" => "TF Test DC2"
  location:    "" => "us/ewr"
  name:        "" => "TFTest3"
profitbricks_datacenter.main: Creation complete (ID: a4e96f1d-9bcd-4aba-8189-7232a07c4992)
profitbricks_lan.lan1: Creating...
  datacenter_id: "" => "a4e96f1d-9bcd-4aba-8189-7232a07c4992"
  name:          "" => "LAN1Public"
  public:        "" => "true"
profitbricks_lan.lan1: Still creating... (10s elapsed)
profitbricks_lan.lan1: Creation complete (ID: 1)
profitbricks_lan.lan2: Creating...
  datacenter_id: "" => "a4e96f1d-9bcd-4aba-8189-7232a07c4992"
  name:          "" => "LAN2Private"
  public:        "" => "false"
profitbricks_lan.lan2: Still creating... (10s elapsed)
profitbricks_lan.lan2: Creation complete (ID: 2)

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

Then if I make a request (using curl or in this case, Postman) against the Cloud API for the list of LANs in that VDC I can see the names of both lans in the items properties.

The request string I'm using looks like this:

https://api.profitbricks.com/cloudapi/v4/datacenters/a4e96f1d-9bcd-4aba-8189-7232a07c4992/lans?depth=1

And the response looks like:

{
    "id": "a4e96f1d-9bcd-4aba-8189-7232a07c4992/lans",
    "type": "collection",
    "href": "https://api.profitbricks.com/cloudapi/v4/datacenters/a4e96f1d-9bcd-4aba-8189-7232a07c4992/lans",
    "items": [
        {
            "id": "2",
            "type": "lan",
        ...
            "properties": {
                "name": "LAN2Private",
                "ipFailover": [],
                "public": false
            },
        ...
        {
        "id": "1",
        ...
            "properties": {
                "name": "LAN1Public",
                "ipFailover": [],
                "public": true
            },

That output was truncated to focus on properties, but you should see something similar.

I have noticed that trying to view the LANs in the DCD is not working quite right. It doesn't seem to be displaying them the same way that the API says they are provisioned. Is that what you were running into?

Eric