Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
atrull committed Nov 17, 2023
1 parent 88eb890 commit c2f8f40
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Overbuilt myip module

Collect and determine what is probably our source ip, only, providing the most common response, which we hope will always be the most correct.

See variables.tf for variables including the list of sources we can check.

See outputs.tf for outputs.
69 changes: 69 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
terraform {
required_providers {
curl = {
version = "1.0.2"
source = "anschoewe/curl"
}
}
}

# curl is the default method
data "curl" "myip" {
for_each = var.data_provider == "curl" ? toset(var.myip_service_urls) : []
http_method = "GET"
uri = each.key
}

# but we can use http if you prefer
data "http" "myip" {
for_each = var.data_provider == "http" ? toset(var.myip_service_urls) : []
url = each.key
method = "GET"
request_timeout_ms = 500
}

locals {

# build a list of responses
service_response_bodies = var.data_provider == "curl" ? values(data.curl.myip)[*].response : values(data.http.myip)[*].response_body

# remunge it without whitespace as a list of strings
split_output = split(",", replace(trimspace(join(",", local.service_response_bodies)), "/\\s/", ""))

# we test responses for valid v4 or v6
ipv4_matches = [
for cidr in local.split_output : cidr
if can(cidrnetmask("${cidr}/32"))
]
ipv6_matches = [
for cidr in local.split_output : cidr
if can(cidrhost("${cidr}/128", 0))
]

# what follows is a really long winded version of uniq -c | sort -n
ipv4_index_list = [for index, item in local.ipv4_matches : length([for i in slice(local.ipv4_matches, 0, index + 1) : i if i == item])]
ipv4_joined_index = zipmap(local.ipv4_matches, local.ipv4_index_list)
ipv4_reverse_index = { for k, v in local.ipv4_joined_index : v => k... }
ipv4_most_common_response = local.ipv4_reverse_index != {} ? lookup(
local.ipv4_reverse_index,
element(
sort(keys(local.ipv4_reverse_index)),
length(local.ipv4_reverse_index) - 1
)
) : []

# uniq -c | sort -n again but for ipv6
ipv6_index_list = [for index, item in local.ipv6_matches : length([for i in slice(local.ipv6_matches, 0, index + 1) : i if i == item])]
ipv6_joined_index = zipmap(local.ipv6_matches, local.ipv6_index_list)
ipv6_reverse_index = { for k, v in local.ipv6_joined_index : v => k... }
ipv6_most_common_response = local.ipv6_reverse_index != {} ? lookup(
local.ipv6_reverse_index,
element(
sort(keys(local.ipv6_reverse_index)),
length(local.ipv6_reverse_index) - 1
)
) : []

}

# See outputs.tf for where we spit out the winners
16 changes: 16 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

output "ipv4_matches" {
value = local.ipv4_matches
}

output "ipv6_matches" {
value = local.ipv6_matches
}

output "ipv4_most_common_response" {
value = join("", local.ipv4_most_common_response)
}

output "ipv6_most_common_response" {
value = join("", local.ipv6_most_common_response)
}
20 changes: 20 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
variable "myip_service_urls" {
default = [
"https://api.seeip.org",
"https://ipinfo.io/ip",
"https://ifconfig.co",
"https://icanhazip.com",
"https://api.ipify.org",
"https://ifconfig.me",
"https://ipecho.net/plain",
"https://ifconfig.io",
"http://eth0.me/",
"https://ident.me",
"https://ipv4.ident.me",
]
}

variable "data_provider" {
default = "curl"
description = "(curl) or (http) provider are both supported."
}

0 comments on commit c2f8f40

Please sign in to comment.