lord-kyron / terraform-provider-phpipam

Terrform provider for PHPIPAM
https://registry.terraform.io/providers/lord-kyron/phpipam/latest
Apache License 2.0
54 stars 30 forks source link

Added Dynamic IP creation by using API method /addresses/first_free/{id} #7

Closed pavel-z1 closed 4 years ago

pavel-z1 commented 4 years ago

Added Dynamic IP creation by using API method /addresses/first_free/{subnetId}/

HI @lord-kyron , I've prepared new resource that will use phpIPAM API method /addresses/first_free/{subnetId}/

This method don't need execute data source to get new IP address, phpIPAM do it automatically.

This pull request has dependency from https://github.com/paybyphone/phpipam-sdk-go This pull request can be applied only when this commit will be approved https://github.com/paybyphone/phpipam-sdk-go/pull/6

If you have paybyphone contacts, will be great if he could check pull request.

P.S. phpIPAM has bug, related to dynamic IP creation - https://github.com/phpipam/phpipam/issues/2960

lord-kyron commented 4 years ago

Thank you @pavel-z1 ! As far as I understand in order this to work both this pull request and the one in @paybyphone repo should be merged? Unfortunately I don't have any contacts of him, but will try to track him down. However, in the mean time - did you had any chance to look at the "count" feature? Maybe I can contact him at once regarding both (if you have any more commits about this too for his repo) ?

pavel-z1 commented 4 years ago

Hi @lord-kyron , Yes, this will work when both PR will be merged: https://github.com/lord-kyron/terraform-provider-phpipam/pull/7 https://github.com/paybyphone/phpipam-sdk-go/pull/6

Regarding count. This feature already support terraform count method. To the README I've added example of count usage:

data "phpipam_subnet" "subnet" {
  subnet_address = "10.10.2.0"
  subnet_mask    = 24
}

// Reserve the address. Note that we use ignore_changes here to ensure that we
// don't end up re-allocating this address on future Terraform runs.
resource "phpipam_first_free_address" {
  count = 3

  subnet_id   = data.phpipam_subnet.subnet.subnet_id
  hostname    = "tf-test-host.example.internal"
  description = "Managed by Terraform"

  lifecycle {
    ignore_changes = [
      subnet_id,
    ]
  }
}

We have only one problem here. This is phpIPAM bug - https://github.com/phpipam/phpipam/issues/2960 Will will wait when phpIPAM will fix this bug to allow dynamic IP creation in Terraform multithreading mode.

lord-kyron commented 4 years ago

@pavel-z1 - will it be easier to fork the paybyphone/phpipam-sdk-go repo, make the changes and then change the paths in the current code to lead to the new modified repo and re-build the provider then? I tried contacting the only contributor of the repo trough the only channel I found he is active - twitter, but with no success yet. Please, share your toughs!

pavel-z1 commented 4 years ago

@lord-kyron Agree with you. I will create Pull request with updated paths shortly.

lord-kyron commented 4 years ago

@pavel-z1 - great. Fork the repo, update it and then make a new pull request here and I will merge it. I will then try to build it and if it works I will upload new release. Does your changes need specific version of golang to be compiled with?

pavel-z1 commented 4 years ago

Hi @lord-kyron I've used GO version 13 to build provider.

lord-kyron commented 4 years ago

@pavel-z1 - I know you forked paybyphone repo, but did you applied the changes from your initial request to the code there? I mean did you implemented this: https://github.com/paybyphone/phpipam-sdk-go/pull/6

pavel-z1 commented 4 years ago

Hi @lord-kyron Yes, I've added CreateFirstFreeAddress to my repository https://github.com/pavel-z1/phpipam-sdk-go/commit/50fba1e0dd19db95bab636fd77b1f5e31162ccb1

Also, we have great news regarding bug https://github.com/phpipam/phpipam/issues/2960 It already fixed, and available in this branch: git clone -b mysql_locking --recursive https://github.com/phpipam/phpipam.git phpipam-locking

So, we already can use dynamic IP provisioning.

To build terraform provider need only execute:

go install
go build
lord-kyron commented 4 years ago

@pavel-z1 I've build the provider with latest terraform 0.12.23 and with latest released go lang 1.14 successfully. However, when I try to use your implementation with the following config:

data "phpipam_subnet" "subnet" {
  subnet_address = "10.128.130.0"
  subnet_mask    = 24
}

resource "phpipam_first_free_address" "new_ip" {
  count = 2

  subnet_id   = data.phpipam_subnet.subnet.subnet_id
  hostname    = "tf-test-host%d.test.internal"
  description = "Managed by Terraform"

  lifecycle {
    ignore_changes = [
      subnet_id,
    ]
  }
}

I am getting the following error:

phpipam_first_free_address.new_ip[1]: Creating...
phpipam_first_free_address.new_ip[0]: Creating...

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

Can you suggest - is this cause because I am using PHPipam 1.4 (not the patched mysql_locking branch) version, or it is something wrong with the provider function?

pavel-z1 commented 4 years ago

@lord-kyron I've perform testing plugin only with phpIPAM latest versions 1.4 and 1.5 (git clone -b mysql_locking --recursive https://github.com/phpipam/phpipam.git phpipam-locking)

On all current phpIPAM releases (<1.5) exists bug with multithreading. Try to use terraform with limit to one thread:

terraform refresh -parallelism=1
terraform apply -parallelism=1

On current development branch issue with multithread was fixed. Tested phpIPAM on branch phpipam-locking Able to use terraform without -parallelism=1 for many IPs.

lord-kyron commented 4 years ago

I've tried with parallelism=1 and still getting:

phpipam_first_free_address.new_ip[1]: Creating...
phpipam_first_free_address.new_ip[0]: Creating...

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

It seems to me something else, like the URL that the new resource type constructs from what I am giving as parameters is somehow wrong and it does not exist.

On planning process it seems fine, but it fails like this when I try to apply it. I am using IPAM 1.4 actually.

lord-kyron commented 4 years ago

Yes, @pavel-z1 indeed it seems that it tries to hit some wrong URL. For example I've tried to access wrong URL from the browser and IPAM is returning the same error to me, when I do: image The question is - I am giving the right components for the provider to connect obviously as it is connecting and planing the right way. Maybe the new resource is not compiling the URL needed to access the IPAM as it should be or it is another problem?

pavel-z1 commented 4 years ago

@lord-kyron Seems you try use terraform provider with app_id that is not configured in phpIPAM.

This is example from my configuration. Terraform:

provider "phpipam" {
  app_id   = "terraform"
  endpoint = "http://ip_address/api"
  password = "pass"
  username = "admi user"
}

phpIPAM: https://monosnap.com/file/5Jp96ZlqigjojpWX9Sg5q1IbrofyhT

app_id in terraform configuration should be the same as configured in phpIPAM.

Can you please recheck phpIPAM API configuration and terraform provider params?

lord-kyron commented 4 years ago

@pavel-z1 my phpipam app_id is "myapp" I am already using it with Ansible and was using it with the older version of the provider. Also, interesting is that when I enter the same address in the browser - I am going to the right place, but when I use it in the provider, I am getting 404

lord-kyron commented 4 years ago

@pavel-z1 - here is the full debug log from terraform when planning and then applying the changes that I am describing. Hope it can help to debug this:

terraform apply -parallelism=1
2020/03/12 14:58:47 [WARN] Log levels other than TRACE are currently unreliable, and are supported only for backward compatibility.
  Use TF_LOG=TRACE to see Terraform's internal logs.
  ----
2020/03/12 14:58:47 [INFO] Terraform version: 0.12.23  
2020/03/12 14:58:47 [INFO] Go runtime version: go1.12.13
2020/03/12 14:58:47 [INFO] CLI args: []string{"/opt/terraform/terraform", "apply", "-parallelism=1"}
2020/03/12 14:58:47 [DEBUG] Attempting to open CLI config file: /home/.terraformrc
2020/03/12 14:58:47 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2020/03/12 14:58:47 [DEBUG] checking for credentials in "/home/.terraform.d/plugins"
2020/03/12 14:58:47 [INFO] CLI command args: []string{"apply", "-parallelism=1"}
2020/03/12 14:58:47 [WARN] Log levels other than TRACE are currently unreliable, and are supported only for backward compatibility.
  Use TF_LOG=TRACE to see Terraform's internal logs.
  ----
2020/03/12 14:58:47 [DEBUG] New state was assigned lineage "bf6f3f19-a3d7-f838-35df-5c08a8e0oj41"
2020/03/12 14:58:47 [DEBUG] checking for provider in "."
2020/03/12 14:58:47 [DEBUG] checking for provider in "/opt/terraform"
2020/03/12 14:58:47 [DEBUG] checking for provider in ".terraform/plugins/linux_amd64"
2020/03/12 14:58:47 [DEBUG] checking for provider in "/home/.terraform.d/plugins"
2020/03/12 14:58:47 [WARN] found legacy provider "terraform-provider-phpipam"
2020/03/12 14:58:47 [DEBUG] found valid plugin: "phpipam", "0.0.0", "/home/.terraform.d/plugins/terraform-provider-phpipam"
2020/03/12 14:58:47 [DEBUG] checking for provisioner in "."
2020/03/12 14:58:47 [DEBUG] checking for provisioner in "/opt/terraform"
2020/03/12 14:58:47 [DEBUG] checking for provisioner in ".terraform/plugins/linux_amd64"
2020/03/12 14:58:47 [DEBUG] checking for provisioner in "/home/.terraform.d/plugins"
2020/03/12 14:58:47 [INFO] backend/local: starting Apply operation
2020-03-12T14:58:47.618Z [INFO]  plugin: configuring client automatic mTLS
2020-03-12T14:58:47.650Z [DEBUG] plugin: starting plugin: path=/home/.terraform.d/plugins/terraform-provider-phpipam args=[/home/.terraform.d/plugins/terraform-provider-phpipam]
2020-03-12T14:58:47.650Z [DEBUG] plugin: plugin started: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130650
2020-03-12T14:58:47.650Z [DEBUG] plugin: waiting for RPC address: path=/home/.terraform.d/plugins/terraform-provider-phpipam
2020-03-12T14:58:47.659Z [INFO]  plugin.terraform-provider-phpipam: configuring server automatic mTLS: timestamp=2020-03-12T14:58:47.659Z
2020-03-12T14:58:47.691Z [DEBUG] plugin: using plugin: version=5
2020-03-12T14:58:47.691Z [DEBUG] plugin.terraform-provider-phpipam: plugin address: address=/tmp/plugin861585933 network=unix timestamp=2020-03-12T14:58:47.691Z
2020-03-12T14:58:47.764Z [DEBUG] plugin: plugin process exited: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130650
2020-03-12T14:58:47.764Z [DEBUG] plugin: plugin exited
2020/03/12 14:58:47 [INFO] terraform: building graph: GraphTypeValidate
2020/03/12 14:58:47 [DEBUG] ProviderTransformer: "phpipam_first_free_address.new_ip" (*terraform.NodeValidatableResource) needs provider.phpipam
2020/03/12 14:58:47 [DEBUG] ProviderTransformer: "data.phpipam_subnet.subnet" (*terraform.NodeValidatableResource) needs provider.phpipam
2020/03/12 14:58:47 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip" references: [data.phpipam_subnet.subnet]
2020/03/12 14:58:47 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet" references: []
2020/03/12 14:58:47 [DEBUG] ReferenceTransformer: "provider.phpipam" references: []
2020/03/12 14:58:47 [DEBUG] Starting graph walk: walkValidate
2020-03-12T14:58:47.766Z [INFO]  plugin: configuring client automatic mTLS
2020-03-12T14:58:47.797Z [DEBUG] plugin: starting plugin: path=/home/.terraform.d/plugins/terraform-provider-phpipam args=[/home/.terraform.d/plugins/terraform-provider-phpipam]
2020-03-12T14:58:47.799Z [DEBUG] plugin: plugin started: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130662
2020-03-12T14:58:47.799Z [DEBUG] plugin: waiting for RPC address: path=/home/.terraform.d/plugins/terraform-provider-phpipam
2020-03-12T14:58:47.806Z [INFO]  plugin.terraform-provider-phpipam: configuring server automatic mTLS: timestamp=2020-03-12T14:58:47.806Z
2020-03-12T14:58:47.840Z [DEBUG] plugin.terraform-provider-phpipam: plugin address: address=/tmp/plugin114287294 network=unix timestamp=2020-03-12T14:58:47.840Z
2020-03-12T14:58:47.840Z [DEBUG] plugin: using plugin: version=5
2020-03-12T14:58:47.912Z [DEBUG] plugin: plugin process exited: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130662
2020-03-12T14:58:47.912Z [DEBUG] plugin: plugin exited
2020/03/12 14:58:47 [INFO] backend/local: apply calling Refresh
2020/03/12 14:58:47 [INFO] terraform: building graph: GraphTypeRefresh
2020/03/12 14:58:47 [DEBUG] ProviderTransformer: "data.phpipam_subnet.subnet" (*terraform.NodeRefreshableDataResource) needs provider.phpipam
2020/03/12 14:58:47 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet" references: []
2020/03/12 14:58:47 [DEBUG] ReferenceTransformer: "provider.phpipam" references: []
2020/03/12 14:58:47 [DEBUG] Starting graph walk: walkRefresh
2020-03-12T14:58:47.914Z [INFO]  plugin: configuring client automatic mTLS
2020-03-12T14:58:47.944Z [DEBUG] plugin: starting plugin: path=/home/.terraform.d/plugins/terraform-provider-phpipam args=[/home/.terraform.d/plugins/terraform-provider-phpipam]
2020-03-12T14:58:47.944Z [DEBUG] plugin: plugin started: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130673
2020-03-12T14:58:47.945Z [DEBUG] plugin: waiting for RPC address: path=/home/.terraform.d/plugins/terraform-provider-phpipam
2020-03-12T14:58:47.953Z [INFO]  plugin.terraform-provider-phpipam: configuring server automatic mTLS: timestamp=2020-03-12T14:58:47.953Z
2020-03-12T14:58:47.987Z [DEBUG] plugin.terraform-provider-phpipam: plugin address: address=/tmp/plugin379691844 network=unix timestamp=2020-03-12T14:58:47.987Z
2020-03-12T14:58:47.987Z [DEBUG] plugin: using plugin: version=5
2020-03-12T14:58:48.056Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 [DEBUG] Initializing PHPIPAM controllers
2020-03-12T14:58:48.056Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Request Body Debug ................... {}
2020-03-12T14:58:48.217Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Response Body Debug ................... {"code":200,"success":true,"data":{"token":"L3HU51DFkjkl0asd98as890","expires":"2020-03-12 20:57:14"},"time":0.057}
2020-03-12T14:58:48.217Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Request Body Debug ................... {}
2020-03-12T14:58:48.274Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"3","name":"Crown","description":"ip address","masterSection":"0","permissions":"{\"2\":\"2\",\"3\":\"3\",\"6\":\"3\",\"7\":\"1\"}","strictMode":"1","subnetOrdering":"default","order":null,"editDate":"2020-01-06 13:14:19","showVLAN":"1","showVRF":"0","DNS":null,"showSupernetOnly":"0","links":[{"rel":"self","href":"\/api\/myapp\/sections\/3\/"}],"custom_fields":null}],"time":0.002}
2020/03/12 14:58:48 [DEBUG] Resource state not found for node "data.phpipam_subnet.subnet", instance data.phpipam_subnet.subnet
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet" references: []
data.phpipam_subnet.subnet: Refreshing state...
2020-03-12T14:58:48.277Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Request Body Debug ................... {}
2020-03-12T14:58:48.337Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"1780","subnet":"10.128.130.0","mask":"24","sectionId":"3","description":"Shared","firewallAddressObject":null,"vrfId":"0","masterSubnetId":"1629","allowRequests":"0","vlanId":"13","showName":"1","device":"0","permissions":"{\"2\":\"2\",\"7\":\"1\"}","pingSubnet":"0","discoverSubnet":"0","DNSrecursive":"0","DNSrecords":"0","nameserverId":"0","scanAgent":"0","isFolder":"0","isFull":"0","tag":"2","editDate":"2020-01-06 13:10:06","linked_subnet":null,"lastScan":null,"lastDiscovery":null,"resolveDNS":"0","threshold":"0","location":"0","custom_AS-New":null,"customer_id":null,"links":[{"rel":"self","href":"\/api\/myapp\/subnets\/1780\/"}],"custom_fields":{"custom_Site":"Florida1","custom_AS":"AS-53081"}}],"time":0.006}
2020-03-12T14:58:48.340Z [DEBUG] plugin: plugin process exited: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130673
2020-03-12T14:58:48.340Z [DEBUG] plugin: plugin exited
2020/03/12 14:58:48 [INFO] backend/local: apply calling Plan
2020/03/12 14:58:48 [INFO] terraform: building graph: GraphTypePlan
2020/03/12 14:58:48 [DEBUG] ProviderTransformer: "phpipam_first_free_address.new_ip" (*terraform.NodePlannableResource) needs provider.phpipam
2020/03/12 14:58:48 [DEBUG] ProviderTransformer: "data.phpipam_subnet.subnet" (*terraform.NodePlannableResource) needs provider.phpipam
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "provider.phpipam" references: []
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip" references: [data.phpipam_subnet.subnet]
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet" references: []
2020/03/12 14:58:48 [DEBUG] Starting graph walk: walkPlan
2020-03-12T14:58:48.343Z [INFO]  plugin: configuring client automatic mTLS
2020-03-12T14:58:48.375Z [DEBUG] plugin: starting plugin: path=/home/.terraform.d/plugins/terraform-provider-phpipam args=[/home/.terraform.d/plugins/terraform-provider-phpipam]
2020-03-12T14:58:48.375Z [DEBUG] plugin: plugin started: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130682
2020-03-12T14:58:48.375Z [DEBUG] plugin: waiting for RPC address: path=/home/.terraform.d/plugins/terraform-provider-phpipam
2020-03-12T14:58:48.384Z [INFO]  plugin.terraform-provider-phpipam: configuring server automatic mTLS: timestamp=2020-03-12T14:58:48.384Z
2020-03-12T14:58:48.416Z [DEBUG] plugin: using plugin: version=5
2020-03-12T14:58:48.416Z [DEBUG] plugin.terraform-provider-phpipam: plugin address: address=/tmp/plugin142951034 network=unix timestamp=2020-03-12T14:58:48.416Z
2020-03-12T14:58:48.484Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 [DEBUG] Initializing PHPIPAM controllers
2020-03-12T14:58:48.484Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Request Body Debug ................... {}
2020-03-12T14:58:48.598Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Response Body Debug ................... {"code":200,"success":true,"data":{"token":"L3HU51DFkjkl0asd98as890","expires":"2020-03-12 20:57:14"},"time":0.011}
2020-03-12T14:58:48.598Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Request Body Debug ................... {}
2020-03-12T14:58:48.654Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:48 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"3","name":"Crown","description":"ip address","masterSection":"0","permissions":"{\"2\":\"2\",\"3\":\"3\",\"6\":\"3\",\"7\":\"1\"}","strictMode":"1","subnetOrdering":"default","order":null,"editDate":"2020-01-06 13:14:19","showVLAN":"1","showVRF":"0","DNS":null,"showSupernetOnly":"0","links":[{"rel":"self","href":"\/api\/myapp\/sections\/3\/"}],"custom_fields":null}],"time":0.002}
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet" references: []
2020/03/12 14:58:48 [DEBUG] Resource instance state not found for node "phpipam_first_free_address.new_ip[0]", instance phpipam_first_free_address.new_ip[0]
2020/03/12 14:58:48 [DEBUG] Resource instance state not found for node "phpipam_first_free_address.new_ip[1]", instance phpipam_first_free_address.new_ip[1]
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip[0]" references: []
2020/03/12 14:58:48 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip[1]" references: []
2020-03-12T14:58:48.662Z [DEBUG] plugin: plugin process exited: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130682
2020-03-12T14:58:48.662Z [DEBUG] plugin: plugin exited

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # phpipam_first_free_address.new_ip[0] will be created
  + resource "phpipam_first_free_address" "new_ip" {
      + address_id        = (known after apply)
2020/03/12 14:58:48 [DEBUG] command: asking for input: "Do you want to perform these actions?"
      + description       = "Managed by Terraform"
      + device_id         = (known after apply)
      + edit_date         = (known after apply)
      + exclude_ping      = (known after apply)
      + hostname          = "tf-test-host.test.internal"
      + id                = (known after apply)
      + ip_address        = (known after apply)
      + is_gateway        = (known after apply)
      + last_seen         = (known after apply)
      + mac_address       = (known after apply)
      + note              = (known after apply)
      + owner             = (known after apply)
      + ptr_record_id     = (known after apply)
      + skip_ptr_record   = (known after apply)
      + state_tag_id      = (known after apply)
      + subnet_id         = 1780
      + switch_port_label = (known after apply)
    }

  # phpipam_first_free_address.new_ip[1] will be created
  + resource "phpipam_first_free_address" "new_ip" {
      + address_id        = (known after apply)
      + description       = "Managed by Terraform"
      + device_id         = (known after apply)
      + edit_date         = (known after apply)
      + exclude_ping      = (known after apply)
      + hostname          = "tf-test-host.test.internal"
      + id                = (known after apply)
      + ip_address        = (known after apply)
      + is_gateway        = (known after apply)
      + last_seen         = (known after apply)
      + mac_address       = (known after apply)
      + note              = (known after apply)
      + owner             = (known after apply)
      + ptr_record_id     = (known after apply)
      + skip_ptr_record   = (known after apply)
      + state_tag_id      = (known after apply)
      + subnet_id         = 1780
      + switch_port_label = (known after apply)
    }

Plan: 2 to add, 0 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
2020/03/12 14:58:56 [INFO] backend/local: apply calling Apply
2020/03/12 14:58:56 [INFO] terraform: building graph: GraphTypeApply
2020/03/12 14:58:56 [DEBUG] Resource state not found for node "phpipam_first_free_address.new_ip[1]", instance phpipam_first_free_address.new_ip[1]
2020/03/12 14:58:56 [DEBUG] Resource state not found for node "phpipam_first_free_address.new_ip[0]", instance phpipam_first_free_address.new_ip[0]
2020/03/12 14:58:56 [DEBUG] ProviderTransformer: "data.phpipam_subnet.subnet (prepare state)" (*terraform.NodeApplyableResource) needs provider.phpipam
2020/03/12 14:58:56 [DEBUG] ProviderTransformer: "phpipam_first_free_address.new_ip[1]" (*terraform.NodeApplyableResourceInstance) needs provider.phpipam
2020/03/12 14:58:56 [DEBUG] ProviderTransformer: "phpipam_first_free_address.new_ip[0]" (*terraform.NodeApplyableResourceInstance) needs provider.phpipam
2020/03/12 14:58:56 [DEBUG] ProviderTransformer: "phpipam_first_free_address.new_ip (prepare state)" (*terraform.NodeApplyableResource) needs provider.phpipam
2020/03/12 14:58:56 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip (prepare state)" references: []
2020/03/12 14:58:56 [DEBUG] ReferenceTransformer: "data.phpipam_subnet.subnet (prepare state)" references: []
2020/03/12 14:58:56 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip[1]" references: [data.phpipam_subnet.subnet (prepare state)]
2020/03/12 14:58:56 [DEBUG] ReferenceTransformer: "phpipam_first_free_address.new_ip[0]" references: [data.phpipam_subnet.subnet (prepare state)]
2020/03/12 14:58:56 [DEBUG] ReferenceTransformer: "provider.phpipam" references: []
2020/03/12 14:58:56 [DEBUG] Starting graph walk: walkApply

2020-03-12T14:58:56.392Z [INFO]  plugin: configuring client automatic mTLS
2020-03-12T14:58:56.427Z [DEBUG] plugin: starting plugin: path=/home/.terraform.d/plugins/terraform-provider-phpipam args=[/home/.terraform.d/plugins/terraform-provider-phpipam]
2020-03-12T14:58:56.428Z [DEBUG] plugin: plugin started: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130696
2020-03-12T14:58:56.428Z [DEBUG] plugin: waiting for RPC address: path=/home/.terraform.d/plugins/terraform-provider-phpipam
2020-03-12T14:58:56.437Z [INFO]  plugin.terraform-provider-phpipam: configuring server automatic mTLS: timestamp=2020-03-12T14:58:56.436Z
2020-03-12T14:58:56.469Z [DEBUG] plugin.terraform-provider-phpipam: plugin address: address=/tmp/plugin255522334 network=unix timestamp=2020-03-12T14:58:56.469Z
2020-03-12T14:58:56.470Z [DEBUG] plugin: using plugin: version=5
2020-03-12T14:58:56.541Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 [DEBUG] Initializing PHPIPAM controllers
2020-03-12T14:58:56.541Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Request Body Debug ................... {}
2020-03-12T14:58:56.793Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Response Body Debug ................... {"code":200,"success":true,"data":{"token":"L3HU51DFkjkl0asd98as890","expires":"2020-03-12 20:57:22"},"time":0.138}
2020-03-12T14:58:56.793Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Request Body Debug ................... {}
2020-03-12T14:58:56.867Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"3","name":"Crown","description":"ip address","masterSection":"0","permissions":"{\"2\":\"2\",\"3\":\"3\",\"6\":\"3\",\"7\":\"1\"}","strictMode":"1","subnetOrdering":"default","order":null,"editDate":"2020-01-06 13:14:19","showVLAN":"1","showVRF":"0","DNS":null,"showSupernetOnly":"0","links":[{"rel":"self","href":"\/api\/myapp\/sections\/3\/"}],"custom_fields":null}],"time":0.002}
phpipam_first_free_address.new_ip[1]: Creating...
2020/03/12 14:58:56 [DEBUG] phpipam_first_free_address.new_ip[1]: applying the planned Create change
2020-03-12T14:58:56.871Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host.test.internal"}
2020-03-12T14:58:56.922Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Response Body Debug ................... {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [DEBUG] phpipam_first_free_address.new_ip[1]: apply errored, but we're indicating that via the Error pointer rather than returning it: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [ERROR] <root>: eval: *terraform.EvalApplyPost, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [ERROR] <root>: eval: *terraform.EvalSequence, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
phpipam_first_free_address.new_ip[0]: Creating...
2020/03/12 14:58:56 [DEBUG] phpipam_first_free_address.new_ip[0]: applying the planned Create change
2020-03-12T14:58:56.925Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host.test.internal"}
2020-03-12T14:58:56.975Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/12 14:58:56 Response Body Debug ................... {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [DEBUG] phpipam_first_free_address.new_ip[0]: apply errored, but we're indicating that via the Error pointer rather than returning it: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [ERROR] <root>: eval: *terraform.EvalApplyPost, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/12 14:58:56 [ERROR] <root>: eval: *terraform.EvalSequence, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

2020-03-12T14:58:56.982Z [DEBUG] plugin: plugin process exited: path=/home/.terraform.d/plugins/terraform-provider-phpipam pid=130696
2020-03-12T14:58:56.982Z [DEBUG] plugin: plugin exited
pavel-z1 commented 4 years ago

@lord-kyron based on debug, seems used different app_id in phpIPAM and terraform provider. Can you please send screenshot of phpIPAM API configuration page and you terraform provider credential configuration(without login/pass)?

lord-kyron commented 4 years ago

@pavel-z1 - as you requested Screenshot from ipam app_id: image Terraform provider config:

provider "phpipam" {
  app_id   = "myapp"
  endpoint = "http://10.10.10.120/api"
  password = "PASSWORD"
  username = "USERNAME"
}

data "phpipam_subnet" "subnet" {
  subnet_address = "10.128.130.0"
  subnet_mask    = 24
}

resource "phpipam_first_free_address" "new_ip" {
  count = 2

  subnet_id   = data.phpipam_subnet.subnet.subnet_id
  hostname    = "tf-test-host.local"
  description = "Managed by Terraform"

  lifecycle {
    ignore_changes = [
      subnet_id,
    ]
  }
}
pavel-z1 commented 4 years ago

Hi @lord-kyron I've added debug of Request URL to the phpipam-sdk-go - https://github.com/pavel-z1/phpipam-sdk-go/commit/a1ff3ad17e47f3892a955b5191d9bdceb7875263

Now we will see Request Url and Request Body data. This will help us to debug phpIPAM.

Example of debug results:

2020-03-13T08:06:03.163+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request URL Debug ...................Method: GET, UR: http://10.60.65.21/api/terraform/sections/
2020-03-13T08:06:03.203+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"2","name":"IPv6","description":"Section for IPv6 addresses","masterSection":"0","permissions":"{\"3\":\"1\",\"2\":\"2\"}","strictMode":"1","subnetOrdering":null,"order":null,"editDate":null,"showSubnet":"1","showVLAN":"0","showVRF":"0","showSupernetOnly":"0","DNS":null},{"id":"1","name":"Rotterdam DC02","description":"Section for customers","masterSection":"0","permissions":"{\"2\":\"2\",\"3\":\"1\"}","strictMode":"1","subnetOrdering":"default","order":null,"editDate":"2020-03-12 10:56:24","showSubnet":"1","showVLAN":"0","showVRF":"0","showSupernetOnly":"0","DNS":null}],"time":0.004}
phpipam_first_free_address.new_ip[0]: Creating...
2020/03/13 08:06:03 [DEBUG] phpipam_first_free_address.new_ip[0]: applying the planned Create change
2020-03-13T08:06:03.208+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host%d.test.internal"}
2020-03-13T08:06:03.208+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request URL Debug ...................Method: POST, UR: http://10.60.65.21/api/terraform/addresses/first_free/8
2020-03-13T08:06:03.264+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Response Body Debug ................... {"code":201,"success":true,"message":"Address created","id":"41","data":"192.168.2.2","time":0.019}
2020-03-13T08:06:03.264+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 [DEBUG] Start Reading IP Address ..............
2020-03-13T08:06:03.264+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request Body Debug ................... {}
2020-03-13T08:06:03.265+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request URL Debug ...................Method: GET, UR: http://10.60.65.21/api/terraform/addresses/search/192.168.2.2/
2020-03-13T08:06:03.308+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"41","subnetId":"8","ip":"192.168.2.2","is_gateway":"0","description":"Managed by Terraform","hostname":"tf-test-host%d.test.internal","mac":null,"owner":null,"tag":"2","deviceId":null,"location":null,"port":null,"note":null,"lastSeen":"1970-01-01 00:00:01","excludePing":"0","PTRignore":"0","PTR":"0","firewallAddressObject":null,"editDate":null,"customer_id":null}],"time":0.007}
phpipam_first_free_address.new_ip[0]: Creation complete after 0s [id=41]
phpipam_first_free_address.new_ip[1]: Creating...
2020/03/13 08:06:03 [DEBUG] phpipam_first_free_address.new_ip[1]: applying the planned Create change
2020-03-13T08:06:03.322+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host%d.test.internal"}
2020-03-13T08:06:03.322+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request URL Debug ...................Method: POST, UR: http://10.60.65.21/api/terraform/addresses/first_free/8
2020-03-13T08:06:03.374+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Response Body Debug ................... {"code":201,"success":true,"message":"Address created","id":"42","data":"192.168.2.3","time":0.017}
2020-03-13T08:06:03.374+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 [DEBUG] Start Reading IP Address ..............
2020-03-13T08:06:03.374+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request Body Debug ................... {}
2020-03-13T08:06:03.374+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Request URL Debug ...................Method: GET, UR: http://10.60.65.21/api/terraform/addresses/search/192.168.2.3/
2020-03-13T08:06:03.417+0100 [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:06:03 Response Body Debug ................... {"code":200,"success":true,"data":[{"id":"42","subnetId":"8","ip":"192.168.2.3","is_gateway":"0","description":"Managed by Terraform","hostname":"tf-test-host%d.test.internal","mac":null,"owner":null,"tag":"2","deviceId":null,"location":null,"port":null,"note":null,"lastSeen":"1970-01-01 00:00:01","excludePing":"0","PTRignore":"0","PTR":"0","firewallAddressObject":null,"editDate":null,"customer_id":null}],"time":0.006}

Please rebuild your terraform-provider-phpipam and execute terraform again:

terraform apply -parallelism=1

Send please results of terraform debug.

lord-kyron commented 4 years ago

@pavel-z1

phpipam_first_free_address.new_ip[0]: Creating...
2020/03/13 08:14:17 [DEBUG] phpipam_first_free_address.new_ip[0]: applying the planned Create change
2020-03-13T08:14:17.287Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host"}
2020-03-13T08:14:17.287Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Request URL Debug ...................Method: POST, UR: http://10.10.10.120/api/myapp/addresses/first_free/1780
2020-03-13T08:14:17.337Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Response Body Debug ................... {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [DEBUG] phpipam_first_free_address.new_ip[0]: apply errored, but we're indicating that via the Error pointer rather than returning it: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [ERROR] <root>: eval: *terraform.EvalApplyPost, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [ERROR] <root>: eval: *terraform.EvalSequence, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
phpipam_first_free_address.new_ip[1]: Creating...
2020/03/13 08:14:17 [DEBUG] phpipam_first_free_address.new_ip[1]: applying the planned Create change
2020-03-13T08:14:17.342Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Request Body Debug ................... {"description":"Managed by Terraform","hostname":"tf-test-host"}
2020-03-13T08:14:17.342Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Request URL Debug ...................Method: POST, UR: http://10.10.10.120/api/myapp/addresses/first_free/1780
2020-03-13T08:14:17.393Z [DEBUG] plugin.terraform-provider-phpipam: 2020/03/13 08:14:17 Response Body Debug ................... {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [DEBUG] phpipam_first_free_address.new_ip[1]: apply errored, but we're indicating that via the Error pointer rather than returning it: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [ERROR] <root>: eval: *terraform.EvalApplyPost, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}
2020/03/13 08:14:17 [ERROR] <root>: eval: *terraform.EvalSequence, err: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

Error: Non-API error (404 Not Found): {"code":404,"success":0,"message":"Invalid URL"}

  on main.tf line 13, in resource "phpipam_first_free_address" "new_ip":
  13: resource "phpipam_first_free_address" "new_ip" {

2020-03-13T08:14:17.399Z [DEBUG] plugin: plugin process exited: path=/home/ansible/.terraform.d/plugins/terraform-provider-phpipam pid=156574
2020-03-13T08:14:17.399Z [DEBUG] plugin: plugin exited
lord-kyron commented 4 years ago

Aaah @pavel-z1 - I think I found the problem. When I try to access the same address like this: http://10.10.10.120/api/myapp/addresses/first_free/1780 - it returns me 404, but when I add "/" on the end like this: http://10.10.10.120/api/myapp/addresses/first_free/1780/ - then it seems to be working!

I am working on phpIPAM IP address management [v1.4]

pavel-z1 commented 4 years ago

@lord-kyron , thank you for information. Fix was added https://github.com/pavel-z1/phpipam-sdk-go/commit/d0ff3300814c6a264161e5555c0554fd3247c270

Try to rebuild provider now.

lord-kyron commented 4 years ago

@pavel-z1 - thank you! Working like a charm now! Can you also update the go.mod in my terraform-provider-phpipam repo and change the version, timestamp and release for this plugin to this latest fixed one? Thank you!

pavel-z1 commented 4 years ago

@lord-kyron Done https://github.com/lord-kyron/terraform-provider-phpipam/commit/f75f482798953e710bb2bb2adbeade07d0619d34

lord-kyron commented 4 years ago

Wonderful! Thank you very much for all your work! Hope you will continue to contribute to this project! I've added new major release of the provider v1.0 because it now supports this crucial functionality! Thanks once again!

pavel-z1 commented 4 years ago

Thank you too for help with testing and new release.

lord-kyron commented 4 years ago

@pavel-z1 - I have some terraform difficulty, that I am trying to get over but I cannot understand if and how it can be done. I was wondering if you have some knowledge / experience about it - I am trying to use two providers this terraform-phpipam-rpovider and vsphere provider together and in one single build to reserve IPs in IPAM with the first module, then expose them to the second provider and use then in the vsphere provider build. Can you help me somehow with that? Thank you!

pavel-z1 commented 4 years ago

Hi @lord-kyron

On this page terraform well described case that you need - https://www.terraform.io/docs/modules/composition.html

  source = "modules/azurerm-k8s-cluster"

  # (Azure-specific configuration arguments)
}

module "monitoring_tools" {
  source = "modules/monitoring_tools"

  cluster_hostname = module.k8s_cluster.hostname
}

Hostname from module k8s_cluster is used in the module monitoring_tools

In you case you need define two modules in one place. In the second (vsphere) use ip resource from second module. For example:

module.module1.phpipam_address.ip_address
lord-kyron commented 4 years ago

@pavel-z1 - thank you@ I've successfully created several modules and they are working like charm! Thank you so much!

lord-kyron commented 4 years ago

@pavel-z1 - do you know how can I (even IF it can be done) use the data to check if ip adress is already existing in IP (by hostname for example) and reserve the next free IP address from the subnet, only if an address with the same hostname is not already present?

I've tried to get data for the address_search for the subnet and the resource to depends_on this data, but it created the IP anyway even if it was existing.

pavel-z1 commented 4 years ago

Hi @lord-kyron ,

In you case, better to use datasource - phpipam_addresses You can use parameter hostname to search ip with hostname.

Example from ReadMe: The phpipam_addresses Data Source

The phpipam_addresses data source allows you to search for IP addresses, much in the same way as you can in the single-form phpipam_address data source. However, multiple addresses are returned from this data source as a single list of address IDs as they are found in the PHPIPAM database. You can then use the single-form phpipam_address data source to extract the IP data for each matched address in the database.

Example:

⚠️ NOTE: The below example requires Terraform v0.12.0 or later!

data "phpipam_addresses" "address_search" {
  subnet_id = 3

  custom_field_filter {
    CustomTestAddresses = ".*terraform.*"
  }
}

data "phpipam_address" "addresses" {
  count      = length(data.phpipam_addresses.address_search.address_ids)
  address_id = element(data.phpipam_addresses.address_search.address_ids, count.index)
}

output "ip_addresses" {
  value = [data.phpipam_address.addresses.*.ip_address]
}

Argument Reference

The data source takes the following parameters:

subnet_id (Required) - The ID of the subnet that the address resides in. This is required to search on the description or hostname fields. One of the following fields is required alongside subnet_id:

description - The description of the IP address. subnet_id is required when using this field. hostname - The host name of the IP address. subnet_id is required when using this field. custom_field_filter - A map of custom fields to search for. The filter values are regular expressions that follow the RE2 syntax for which you can find documentation here. All fields need to match for the match to succeed. ⚠️ NOTE: An empty or unspecified custom_field_filter value is the equivalent to a regular expression that matches everything, and hence will return all addresses that contain the referenced custom field key!

jordips commented 4 years ago

Hi everyone,

I'm facing the same problem trying to automate with terraform. I agree that php-ipam has to add this improvement. @lord-kyron first of all thanks for provider v1 (including count feature). Regarding to: ...you must apply this fix: phpipam/phpipam@b634cb9...

it only applies to v1.4. I tried to patch v1.3 but it has Mysql PDO problems.

For people that need a workaround (beeing at v1.3 and can't upgrade to 1.4), can be accomplished by phpipam_addresses:

#!/bin/bash
TOKEN=$(curl -sS -X POST --user <user>:<password> -H 'Content-type: application/json' https://<server-ipam>/api/<clientid>/user/ | jq -r '.data.token')
echo -n "{\"token\":\"${TOKEN}\"}
data "phpipam_addresses" "address_search" {
  subnet_id = data.phpipam_subnet.subnet.subnet_id
  description = "DESCRIPTION_TO_SEARCH"
}

data "phpipam_address" "addresses" {
  count      = "${length(data.phpipam_addresses.address_search.address_ids)}"
  address_id = "${element(data.phpipam_addresses.address_search.address_ids, count.index)}"
}

data "external" "phpipam_login" {
  program = ["bash", "${path.module}/phpipam-login.sh"]
}

# Change description and other attributes of each IP (description has to be changed!)
# Add to --data as many attributes you want to change for "reserve"
resource "null_resource" "phpipam_assignip" {
  count = 3
  provisioner "local-exec" {
    command = "curl -sS -X PATCH --data '{\"description\":\"Assigned!\"}' -H 'Content-type: application/json' -H 'token: ${data.external.phpipam_login.result["token"]}' https://<server-ipam>/api/<client-id>/addresses/${data.phpipam_address.addresses[count.index].id}/" 
  }
}

Obviusly, It's not a solution... but if anyone needs something fast... may help

raffus commented 4 years ago

Hi there,

I'm facing same issue.

This is what terraform creates when using multiple provisioning:

Terraform will perform the following actions:

  # phpipam_address.address[0] will be created
  + resource "phpipam_address" "address" {
      + address_id           = (known after apply)
      + description          = "Managed by Terraform"
      + device_id            = (known after apply)
      + edit_date            = (known after apply)
      + exclude_ping         = (known after apply)
      + hostname             = "transacional-core-1.mydomain.comr"
      + id                   = (known after apply)
      + ip_address           = "10.10.1.1"
      + is_gateway           = (known after apply)
      + last_seen            = (known after apply)
      + mac_address          = (known after apply)
      + note                 = (known after apply)
      + owner                = (known after apply)
      + ptr_record_id        = (known after apply)
      + remove_dns_on_delete = true
      + skip_ptr_record      = (known after apply)
      + state_tag_id         = (known after apply)
      + subnet_id            = 63
      + switch_port_label    = (known after apply)
    }

  # phpipam_address.address[1] will be created
  + resource "phpipam_address" "address" {
      + address_id           = (known after apply)
      + description          = "Managed by Terraform"
      + device_id            = (known after apply)
      + edit_date            = (known after apply)
      + exclude_ping         = (known after apply)
      + hostname             = "transacional-core-2.mydomain.comr"
      + id                   = (known after apply)
      + ip_address           = "10.10.1.1"
      + is_gateway           = (known after apply)
      + last_seen            = (known after apply)
      + mac_address          = (known after apply)
      + note                 = (known after apply)
      + owner                = (known after apply)
      + ptr_record_id        = (known after apply)
      + remove_dns_on_delete = true
      + skip_ptr_record      = (known after apply)
      + state_tag_id         = (known after apply)
      + subnet_id            = 63
      + switch_port_label    = (known after apply)
    }

  # phpipam_address.address[2] will be created
  + resource "phpipam_address" "address" {
      + address_id           = (known after apply)
      + description          = "Managed by Terraform"
      + device_id            = (known after apply)
      + edit_date            = (known after apply)
      + exclude_ping         = (known after apply)
      + hostname             = "transacional-core-3.mydomain.comr"
      + id                   = (known after apply)
      + ip_address           = "10.10.1.1"
      + is_gateway           = (known after apply)
      + last_seen            = (known after apply)
      + mac_address          = (known after apply)
      + note                 = (known after apply)
      + owner                = (known after apply)
      + ptr_record_id        = (known after apply)
      + remove_dns_on_delete = true
      + skip_ptr_record      = (known after apply)
      + state_tag_id         = (known after apply)
      + subnet_id            = 63
      + switch_port_label    = (known after apply)
    }

Then when creating:

vsphere_folder.folder: Creating...
phpipam_address.address[1]: Creating...
phpipam_address.address[1]: Creation complete after 1s [id=6566]
phpipam_address.address[0]: Creating...
phpipam_address.address[2]: Creating...

Error: Error from API (409): IP address already exists

  on main.tf line 15, in resource "phpipam_address" "address":
  15: resource "phpipam_address" "address" {

Error: Error from API (409): IP address already exists

  on main.tf line 15, in resource "phpipam_address" "address":
  15: resource "phpipam_address" "address" {

Error: error creating folder: ServerFaultCode: The name 'TRANSACIONAL-CORE' already exists.

  on main.tf line 60, in resource "vsphere_folder" "folder":
  60: resource "vsphere_folder" "folder" {

My resource config:

resource "phpipam_address" "address" {
  count       = var.vm_count
  subnet_id   = data.phpipam_subnet.subnet.subnet_id
  ip_address  = data.phpipam_first_free_address.next_address.ip_address
  hostname    = "transacional-core-${count.index+1}.mydomain.com"
  description = "Managed by Terraform"

  lifecycle {
    ignore_changes = [
      subnet_id
    ]
  }
}

And my vsphere resource:

resource "vsphere_virtual_machine" "cloned_virtual_machine" {
  count            = var.vm_count
  name             = "${var.vsphere_virtual_machine_name} ${count.index+1}"
  resource_pool_id = data.vsphere_resource_pool.pool.id
  datastore_id     = data.vsphere_datastore.datastore.id
  folder           = var.vsphere_folder
  depends_on  = [phpipam_address.address]

  num_cpus = 1
  memory   = 2048

  guest_id = data.vsphere_virtual_machine.template.guest_id

  scsi_type = data.vsphere_virtual_machine.template.scsi_type

  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
  }

  disk {
    label = "disk0"
    size = data.vsphere_virtual_machine.template.disks.0.size
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.template.id
    customize {
      linux_options {
        host_name = "${var.vsphere_virtual_machine_name} ${count.index+1}"
        domain = "mydomain.com"
      }

      network_interface {
        ipv4_address = data.phpipam_first_free_address.next_address.ip_address
        ipv4_netmask = 24
      }

      dns_suffix_list = ["mydomain.com"]
      dns_server_list = ["8.8.8.8"]
      ipv4_gateway = "10.10.1.1"
    }
  }
}

Am I missing something here?

Best regards, Rafael