TritonDataCenter / terraform-provider-triton

Terraform Joyent Triton provider
https://www.terraform.io/docs/providers/triton/
Mozilla Public License 2.0
15 stars 24 forks source link

Terraform falsely reports success when adding an invalid network #86

Closed watters closed 6 years ago

watters commented 6 years ago

Terraform Version

Terraform v0.11.3
+ provider.triton v0.4.1

Affected Resource(s)

Terraform Configuration Files

data "triton_network" "public" {
  name = "Joyent-SDC-Public"
}

data "triton_image" "ubuntu" {
  name        = "ubuntu-16.04"
  type        = "lx-dataset"
  most_recent = true
}

resource "triton_machine" "foo" {
  name    = "foo"

  package = "g4-general-4G"
  image   = "${data.triton_image.ubuntu.id}"

  // the public network for whatever datacenter I'm on
  networks = [
    "${data.triton_network.public.id}"
  ]
/*
  // the second network in this block is a network that you don't have access to
  networks = [
    "${data.triton_network.public.id}",
    "b774bda4-b5a7-40a4-88a3-8d1223d7257a"
  ]
*/
  firewall_enabled = false
}

Debug Output

Debug output

Expected Behavior

I'd hope that Terraform would tell me that my config includes a network that I don't have access to. It's worth noting that, if this network is present when the instance is created, the creation fails. It only reports success when modifying an existing instance.

Actual Behavior

Terraform reported that it successfully changed my instance without reporting anything amiss.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply using the above config
  2. triton inst get foo to inspect the instance you just created; should only have a single nic
  3. edit the config to un-comment the networks block with two networks and comment/remove the block with only the public network—the second network is one you don't have access to, so the operation should fail.
  4. terraform apply with this edited file
  5. observe that terraform reports success: Apply complete! Resources: 0 added, 1 changed, 0 destroyed. This is wrong. It doesn't actually add the second network.
  6. triton inst get foo to inspect the instance after the change and note that it still only has the one network.

Bonus Bug?

(append to previous steps)

  1. edit the config so that only the public network is listed again (i.e. remove the network you don't have access to).
  2. terraform apply
  3. triton inst get foo — now the instance has two nics on the public network.
  4. sdc-nics list <instance id from previous step> to get details for those nics
stack72 commented 6 years ago

Hey @watters

So this is actually fixed in master due to #84 - I can see that as follows.

  1. I rolled out your configuration:
issue-86 % terraform show
data.triton_image.ubuntu:
  id = 7b5981c4-1889-11e7-b4c5-3f3bdfc9b88b
  most_recent = true
  name = ubuntu-16.04
  type = lx-dataset
data.triton_network.public:
  id = f7ed95d3-faaf-43ef-9346-15644403b963
  name = Joyent-SDC-Public
triton_machine.foo:
  id = 8fe84966-e7fd-4aab-ecf9-aed5da5255a1
  administrator_pw =
  cloud_config =
  dataset = 7b5981c4-1889-11e7-b4c5-3f3bdfc9b88b
  disk = 51200
  domain_names.# = 2
  domain_names.0 = 8fe84966-e7fd-4aab-ecf9-aed5da5255a1.inst.9df26e60-4bc4-eca9-db82-a8ecb0dec126.us-sw-1.triton.zone
  domain_names.1 = foo.inst.9df26e60-4bc4-eca9-db82-a8ecb0dec126.us-sw-1.triton.zone
  firewall_enabled = false
  image = 7b5981c4-1889-11e7-b4c5-3f3bdfc9b88b
  ips.# = 1
  ips.0 = 165.225.157.241
  memory = 4096
  metadata.% = 0
  name = foo
  networks.# = 1
  networks.0 = f7ed95d3-faaf-43ef-9346-15644403b963
  nic.# = 1
  nic.1530435974.gateway = 165.225.156.1
  nic.1530435974.ip = 165.225.157.241
  nic.1530435974.mac = 90:b8:d0:d1:1c:18
  nic.1530435974.netmask = 255.255.254.0
  nic.1530435974.network = 147ee1a3-0489-4d2a-ab29-a747ff5cb66b
  nic.1530435974.primary = true
  nic.1530435974.state = running
  package = g4-general-4G
  primaryip = 165.225.157.241
  root_authorized_keys = 

  tags.% = 0
  type = smartmachine
  user_data =
  user_script =
  1. I updated the machine resource to include a random network UUID
data "triton_network" "public" {
  name = "Joyent-SDC-Public"
}

data "triton_image" "ubuntu" {
  name        = "ubuntu-16.04"
  type        = "lx-dataset"
  most_recent = true
}

resource "triton_machine" "foo" {
  name    = "foo"

  package = "g4-general-4G"
  image   = "${data.triton_image.ubuntu.id}"

  // the public network for whatever datacenter I'm on
  # networks = [
  #   "${data.triton_network.public.id}"
  # ]

  // the second network in this block is a network that you don't have access to
  networks = [
    "${data.triton_network.public.id}",
    "b774bda4-b5a7-40a4-88a3-8d1223d7257a"
  ]

  firewall_enabled = false
}

When I ran a terraform plan I can see the following:

issue-86 % terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.triton_image.ubuntu: Refreshing state...
data.triton_network.public: Refreshing state...
triton_machine.foo: Refreshing state... (ID: 8fe84966-e7fd-4aab-ecf9-aed5da5255a1)

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ triton_machine.foo
      networks.#: "1" => "2"
      networks.1: "" => "b774bda4-b5a7-40a4-88a3-8d1223d7257a"

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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
  1. The terraform apply looked as follows:
issue-86 % terraform apply
data.triton_network.public: Refreshing state...
data.triton_image.ubuntu: Refreshing state...
triton_machine.foo: Refreshing state... (ID: 8fe84966-e7fd-4aab-ecf9-aed5da5255a1)

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ triton_machine.foo
      networks.#: "1" => "2"
      networks.1: "" => "b774bda4-b5a7-40a4-88a3-8d1223d7257a"

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

triton_machine.foo: Modifying... (ID: 8fe84966-e7fd-4aab-ecf9-aed5da5255a1)
  networks.#: "1" => "2"
  networks.1: "" => "b774bda4-b5a7-40a4-88a3-8d1223d7257a"

Error: Error applying plan:

1 error(s) occurred:

* triton_machine.foo: 1 error(s) occurred:

* triton_machine.foo: unable to add NIC to machine: InvalidArgument: network not found

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

This will also fix your bonus bug as well! An extensive refactor of the networks part of instances Update was undertaken in #84

Paul

stack72 commented 6 years ago

Closed via #84