Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ipincidr): add ipincidr function #33037

Closed
wants to merge 1 commit into from
Closed

feat(ipincidr): add ipincidr function #33037

wants to merge 1 commit into from

Conversation

FalcoSuessgott
Copy link

@FalcoSuessgott FalcoSuessgott commented Apr 14, 2023

Hi guys,

I wanted to hear your feedback about the function ipincidr, which checks whether a specified IP is in a given CIDR subnet.

This function would be especially useful for pre/postconditions, where you would check whether a valid subnet/ip combination is correct:

terraform {}

locals {
    ip = "10.100.32.100"
    cidr = "172.16.0.0/16"
}

resource "null_resource" "ip_in_cidr" {

    lifecycle {
        precondition {
        condition     = ipincidr(local.ip, local.cidr)
        error_message = "The IP must be within the specified CIDR subnet."
        }
    }
}

which would fail in


Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Resource precondition failed
│ 
│   on main.tf line 12, in resource "null_resource" "ooo":
│   12:         condition     = ipincidr(local.ip, local.cidr)
│     ├────────────────
│     │ local.cidr is "172.16.0.0/16"
│     │ local.ip is "10.100.32.100"
│ 
│ The IP must be within the specified CIDR subnet.

If that is something that would be interesting, I can finish the remaining documentional todos and changes.

@crw
Copy link
Collaborator

crw commented Apr 18, 2023

Hi @FalcoSuessgott, thanks for this submission! I will bring this up in triage.

I suspect the answer will be that this it would be preferred to build this as a plugin function provider, as opposed to a function built into Terraform. As such it would be waiting for the implementation of plugin function providers, per:

That said, we'll see what the feedback is in triage. Thanks again!

@FalcoSuessgott
Copy link
Author

Hi @FalcoSuessgott, thanks for this submission! I will bring this up in triage.

I suspect the answer will be that this it would be preferred to build this as a plugin function provider, as opposed to a function built into Terraform. As such it would be waiting for the implementation of plugin function providers, per:

That said, we'll see what the feedback is in triage. Thanks again!

I understand, now with some time passed I also see that this function would probably only have limited use cases. Nevertheless I will wait for your feedback in triage. I just want to emphasize that something like custom terraform functions like proposed in the PRs that you linked, would be incredibly useful! Maybe this is something worth considering :)

Best

Tom

@kbolino
Copy link

kbolino commented Jun 15, 2023

If "function provider" means functions written in Go, then you could certainly implement ipincidr (and similar functions) that way. But one of the linked discussions talks more about "custom functions" written in HCL, which would meet a lot of people's needs but not this particular one. For ipincidr to be possible in HCL alone, there would also need to be bitwise operations (either as operators or builtin functions).

@cmd-ntrf
Copy link

I think a potential alternative in pure HCL is to use a for loop and the cidrhost function like this:

alltrue([for i, v in split(".", local.ip): tonumber(split(".", cidrhost(local.cidr, 0))[i]) <= tonumber(v) && tonumber(v) <= tonumber(split(".", cidrhost(local.cidr, -1))[i]) ])

It is definitely more verbose than a ipincidr function, but it solves the problem at hand, and it works in condition:

locals {
 #ip = "10.100.32.100" # not in range - raise error message 
 ip = "172.16.1.16"         # in range, can be successfully applied
 cidr = "172.16.0.0/16"
}

resource "null_resource" "ip_in_cidr" {

    lifecycle {
        precondition {
        condition     = alltrue([for i, v in split(".", local.ip): tonumber(split(".", cidrhost(local.cidr, 0))[i]) <= tonumber(v) && tonumber(v) <= tonumber(split(".", cidrhost(local.cidr, -1))[i]) ])
        error_message = "The IP must be within the specified CIDR subnet."
        }
    }
}

@FalcoSuessgott FalcoSuessgott closed this by deleting the head repository Nov 10, 2023
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants