Skip to content

Conversation

@pavel-z1
Copy link
Collaborator

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 paybyphone/phpipam-sdk-go#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 - phpipam/phpipam#2960

@lord-kyron
Copy link
Owner

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) ?

@lord-kyron lord-kyron merged commit 7045b08 into lord-kyron:master Mar 10, 2020
@pavel-z1
Copy link
Collaborator Author

pavel-z1 commented Mar 10, 2020

Hi @lord-kyron ,
Yes, this will work when both PR will be merged:
#7
paybyphone/phpipam-sdk-go#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 - phpipam/phpipam#2960
Will will wait when phpIPAM will fix this bug to allow dynamic IP creation in Terraform multithreading mode.

@lord-kyron
Copy link
Owner

@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
Copy link
Collaborator Author

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

@lord-kyron
Copy link
Owner

@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
Copy link
Collaborator Author

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

@lord-kyron
Copy link
Owner

lord-kyron commented Mar 12, 2020

@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: paybyphone/phpipam-sdk-go#6

@pavel-z1
Copy link
Collaborator Author

Hi @lord-kyron
Yes, I've added CreateFirstFreeAddress to my repository pavel-z1/phpipam-sdk-go@50fba1e

Also, we have great news regarding bug phpipam/phpipam#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
Copy link
Owner

lord-kyron commented Mar 12, 2020

@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
Copy link
Collaborator Author

pavel-z1 commented Mar 12, 2020

@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
Copy link
Owner

lord-kyron commented Mar 12, 2020

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
Copy link
Owner

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
Copy link
Collaborator Author

pavel-z1 commented Mar 12, 2020

@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
Copy link
Owner

@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
Copy link
Owner

lord-kyron commented Mar 12, 2020

@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
Copy link
Collaborator Author

@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
Copy link
Owner

lord-kyron commented Mar 12, 2020

@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
Copy link
Collaborator Author

Hi @lord-kyron
I've added debug of Request URL to the phpipam-sdk-go - pavel-z1/phpipam-sdk-go@a1ff3ad

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
Copy link
Owner

@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
Copy link
Owner

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
Copy link
Collaborator Author

@lord-kyron , thank you for information.
Fix was added pavel-z1/phpipam-sdk-go@d0ff330

Try to rebuild provider now.

@lord-kyron
Copy link
Owner

@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
Copy link
Collaborator Author

@lord-kyron Done
f75f482

@lord-kyron
Copy link
Owner

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
Copy link
Collaborator Author

Thank you too for help with testing and new release.

@lord-kyron
Copy link
Owner

@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
Copy link
Collaborator Author

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
Copy link
Owner

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

@lord-kyron
Copy link
Owner

@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
Copy link
Collaborator Author

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
Copy link

jordips commented Mar 23, 2020

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:

  • First, you have to add a description (for example: DESCRIPTION_TO_SEARCH) to all IPs you want to get. (I know...it's a workaround). Feel free to change this attribute. Is a conditional to get "free" ips that are already "assigned".

  • Create a file called phpipam-login.sh with this content (maybe you can use token from phpipam provider):

#!/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}\"}
  • Then add this to you tf file (change count parameter as many IPs you want to reserve. You can add more attributes to PATCH curl command):
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
Copy link

raffus commented Sep 16, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants