Skip to content

Applications

FloatingIP-to-DNS

Configuration du DNS

Generate a public/private key pair:

$ tsig-keygen -a HMAC-MD5 www.domain.com.

Configure your DNS zone like this:

...
key "www.domain.com" {
  algorithm hmac-md5;
  secret "the-value-of-the-generated-key-that-you-can-see-in-public-and-private-keys ==";
};
...
zone "domain.com" {
  type master;
  file "/etc/bind/keys.d/domain.com.tsig";
  allow-update { key "www.domain.com."; };
};

Configuration de terraform

main.tf
module cache-openstack-floatingip-to-register {

    source = "./modules/cache-openstack-floatingip-to-register"

    #
    # will be completed as
    # <openstack-project-name>.<openstack-domain-name>.<dns_suffix>
    #
    dns_suffix = var.dns_suffix

    #
    #
    #
    dns_fip_default_ttl = var.dns_fip_default_ttl

}

module register-openstack-floatingip-to-external-dns1 {

    source = "./modules/register-openstack-floatingip-to-external-dns"

    ddns_suffix   = module.cache-openstack-floatingip-to-register.dns_suffix
    ddns_fip_name = module.cache-openstack-floatingip-to-register.dns_fip_name
    ddns_fip_ipv4 = module.cache-openstack-floatingip-to-register.dns_fip_ipv4
    ddns_fip_ttl  = module.cache-openstack-floatingip-to-register.dns_fip_ttl

    ddns_server_ip     = var.dns2__ddns_server_ip
    ddns_key_name      = var.dns2__ddns_key_name
    ddns_key_algorithm = var.dns2__ddns_key_algorithm
    ddns_key_secret    = var.dns2__ddns_key_secret

}

module register-openstack-floatingip-to-external-dns2 {

    source = "./modules/register-openstack-floatingip-to-external-dns"

    ddns_suffix   = module.cache-openstack-floatingip-to-register.dns_suffix
    ddns_fip_name = module.cache-openstack-floatingip-to-register.dns_fip_name
    ddns_fip_ipv4 = module.cache-openstack-floatingip-to-register.dns_fip_ipv4
    ddns_fip_ttl  = module.cache-openstack-floatingip-to-register.dns_fip_ttl

    ddns_server_ip     = var.dns2__ddns_server_ip
    ddns_key_name      = var.dns2__ddns_key_name
    ddns_key_algorithm = var.dns2__ddns_key_algorithm
    ddns_key_secret    = var.dns2__ddns_key_secret

}
terraform__variables.tf
variable dns_suffix {
    type = string
}

variable dns_fip_default_ttl {
    type = number
}
###########################################################################
#
# DNS MASTER 1
#
###########################################################################

variable dns1__ddns_server_ip {
    type = string
}

variable dns1__ddns_key_name {
    type = string
}

variable dns1__ddns_key_algorithm {
    type = string
}

variable dns1__ddns_key_secret {
    type = string
}

###########################################################################
#
# DNS MASTER 2
#
###########################################################################

variable dns2__ddns_server_ip {
    type = string
}

variable dns2__ddns_key_name {
    type = string
}

variable dns2__ddns_key_algorithm {
    type = string
}

variable dns2__ddns_key_secret {
    type = string
}

module/cache-openstack-floatingip-to-register

Info

Le module terraform cache-openstack-floatingip-to-register interroge une instance openstack, sur un projet donné, pour obtenir la liste des floating-ip ainsi que les Tags associés.

terraform
terraform__terraform.tf
terraform {
  required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 1.48.0"
    }
    external = {
      version = "~> 2.2.3"
    }
  }
}
terraform__variables.tf
1
2
3
4
5
6
7
8
variable dns_suffix {
    type = string
}

variable dns_fip_default_ttl {
    type = string
    default = "3600"
}
terraform__locals.tf
locals {

    suffix = lower(join(".", [
       data.openstack_identity_auth_scope_v3.self.project_name,
       data.openstack_identity_auth_scope_v3.self.project_domain_name
    ]))

    ddns_suffix = join(".", [
       local.suffix,
       "microstack."
    ])

#    tag_instance_name = "instance-name=domain-name-server-%02s.${local.suffix}"

}
terraform__outputs.tf
output dns_suffix {
    value = local.ddns_suffix
}

output dns_fip_name {
    value = data.external.openstack_networking_floatingip_name.result
}

output dns_fip_ipv4 {
    value = data.external.openstack_networking_floatingip_ipv4.result
}

output dns_fip_ttl {
    value = data.external.openstack_networking_floatingip_ttl.result
}
data
data__openstack_identity_auth_scope_v3.tf
1
2
3
data openstack_identity_auth_scope_v3 self {
   name = "self"
}
data__external.tf
data external openstack_networking_floatingip {
    program = [ "bash", "${path.module}/external/openstack_networking_floatingip.bash" ]
    query = {
        module_path = abspath(path.module)
        project_name = data.openstack_identity_auth_scope_v3.self.project_name
    }
}

data external openstack_networking_floatingip_name {
    program = [ "bash", "${path.module}/external/openstack_networking_floatingip_name.bash" ]
    query = {
        module_path = abspath(path.module)
        file_path = data.external.openstack_networking_floatingip.result.file_path
    }
}

data external openstack_networking_floatingip_ipv4 {
    program = [ "bash", "${path.module}/external/openstack_networking_floatingip_ipv4.bash" ]
    query = {
        module_path = abspath(path.module)
        file_path = data.external.openstack_networking_floatingip.result.file_path
    }
}

data external openstack_networking_floatingip_ttl {
    program = [ "bash", "${path.module}/external/openstack_networking_floatingip_ttl.bash" ]
    query = {
        module_path = abspath(path.module)
        file_path = data.external.openstack_networking_floatingip.result.file_path
        dns_fip_default_ttl = var.dns_fip_default_ttl
    }
}
external__*
external/openstack_networking_floatingip_ipv4.bash
#!/usr/bin/env bash

set -e
set -u
set -o pipefail

function main {
    local -r input="${1}"
    local -r JQ="$(command -v jq|| exit 1)"
    local -r module_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
            '$input|.module_path'
    )"
    local -r floatingip_cache_file_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
             '$input|.file_path'
    )"

    local -r floatingip_ipv4_cache_file_path="${module_path}/cache/openstack_networking_floatingip_ipv4.json"

    local -r output="$(
        cat "${floatingip_cache_file_path}" \
      | $JQ --raw-output \
            ' 
    map("\"\(.["ID"])\":\"\(.["Floating IP Address"])\"")
  | join(",") as $result
  | "{\($result)}" 
        '
    )"

    printf '%s\n' "${output}" > "${floatingip_ipv4_cache_file_path}"
    cat "${floatingip_ipv4_cache_file_path}" > /dev/stdout
}

main "$( [[ -p /dev/stdin ]] && cat - || echo "$@" )"
external/openstack_networking_floatingip_name.bash
#!/usr/bin/env bash

set -e
set -u
set -o pipefail

function main {
    local -r input="${1}"
    local -r JQ="$(command -v jq|| exit 1)"
    local -r file_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
            '$input|.file_path'
    )"

    cat "${file_path}" \
  | $JQ '   
  map(
       (.["Tags"][]|capture("instance-name=(?<name>.*)")) as $capture
     | {
          key: (.["ID"]),
          value: (
              $capture.name 
            | split(".")
            | .[0]
          )
       }
  )
| from_entries

'
}

main "$( [[ -p /dev/stdin ]] && cat - || echo "$@" )"
external/openstack_networking_floatingip_ttls.bash
#!/usr/bin/env bash

set -e
set -u
set -o pipefail

function main {
    local -r input="${1}"
    local -r JQ="$(command -v jq|| exit 1)"

    local -r module_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
            '$input|.module_path'
    )"
    local -r floatingip_cache_file_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
            '$input|.file_path'
    )"
    local -r dns_default_ttl="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}" \
            '$input|.dns_fip_default_ttl'
    )"

    local -r floatingip_ttl_cache_file_path="${module_path}/cache/openstack_networking_floatingip_ttl.json"

    local -r output="$(
        cat "${floatingip_cache_file_path}" \
      | $JQ --raw-output \
            --arg dns_default_ttl "${dns_default_ttl}" \
            '
  map(
       (.["Tags"][]|capture("dns-ttl=(?<dns_ttl>.*)") // null) as $capture
     | {
          key: (.["ID"]),
          value: (
              if $capture == null then
                  $dns_default_ttl
              else
                  $capture.dns_ttl 
              end                  
          )
       }
  )
| from_entries
            '
    )"

    printf '%s\n' "${output}" > "${floatingip_ttl_cache_file_path}"
    cat "${floatingip_ttl_cache_file_path}" > /dev/stdout
}

main "$( [[ -p /dev/stdin ]] && cat - || echo "$@" )"
external/openstack_networking_gloatingip.bash
#!/usr/bin/env bash

#set -x
set -e
set -u
set -o pipefail

function now {
    date +%Y-%m-%d_%H-%M-%S
}
function main {
    local -r input="${1}"
    local -r JQ="$(command -v jq|| exit 1)"

    printf '%s | %s | input: %s\n' \
           "$(now)" \
           "${0}" \
           "${input}" \
  > debug.log

    local -r module_path="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}"\
            '$input|.module_path'
    )"
    printf '%s | %s | module_path: %s\n' \
           "$(now)" \
           "$0" \
           "${module_path}" \
 >> debug.log

    local -r project_name="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${input}"\
            '$input|.project_name'
    )"
    printf '%s | %s | project_name: %s\n' \
           "$(now)" \
           "$0" \
           "${project_name}" \
 >> debug.log

    local -r file_path="${module_path}/cache/openstack_networking_floatingip.json"    

    local -r items_tags="$(
openstack floating ip list \
    --project "${project_name}" \
    --format json \
    --long \
    --column 'ID' \
    --column 'Floating IP Address' \
    --column 'Tags'
)"
    printf '%s' "${items_tags}" > "${file_path}.raw"

    local -r filtered_items_tags="$(
        $JQ --null-input \
            --raw-output \
            --argjson input "${items_tags}" \
            '
   $input   
 | map(
     if (.["Tags"]|type)=="array" and .["Tags"] != [] 
     then .
     else empty
     end
  )
            '
    )"
    printf '%s' "${filtered_items_tags}" > "${file_path}"


    local -r output="$(
        $JQ --null-input \
            --arg file_path "${file_path}" \
            '
{
  file_path: $file_path
}
' 
    )"

    printf '%s' "${output}" > /dev/stdout
}

main "$( [[ -p /dev/stdin ]] && cat - || echo "$@" )"

module/register-openstack-floatingip-to-external-dns

terraform__*

Info

Le module terraform register-openstack-floatingip-to-external-dns enregistre les floating-ip dans le DNS si besoin, en utilisant les informations collectées via le module terraform cache-openstack-floatingip-to-register.

terraform__terraform.tf
1
2
3
4
5
6
7
8
9
terraform {
  required_version = ">= 0.14.0"
  required_providers {
    dns = {
      source = "hashicorp/dns"
      version = "~> 3.2.3"
    }
  }
}
terraform__providers.tf
1
2
3
4
5
6
7
8
9
provider dns {
  update {
     server = var.ddns_server_ip
     key_name = var.ddns_key_name
     key_algorithm = var.ddns_key_algorithm
#     key_algorithm = "hmac-md5"
     key_secret = var.ddns_key_secret
  }
}
terraform__variables.tf
variable ddns_suffix {
   type = string
}

variable ddns_fip_name {
    type = map
}

variable ddns_fip_ipv4 {
    type = map
}

variable ddns_fip_ttl {
    type = map
}

variable ddns_server_ip {
    type = string
}

variable ddns_key_name {
    type = string
    default = "terraform"
}

variable ddns_key_algorithm {
    type = string
    default = "hmac-md5"
}

variable ddns_key_secret {
    type = string
}
resource__*
resource__dns_a_record_set.tf
resource dns_a_record_set record {

    for_each = var.ddns_fip_name

    name = each.value
    zone = var.ddns_suffix
    addresses = [
        lookup(var.ddns_fip_ipv4, each.key)
    ]
    ttl = tonumber(lookup(var.ddns_fip_ttl, each.key))

}