terraform-provider-digitalocean icon indicating copy to clipboard operation
terraform-provider-digitalocean copied to clipboard

resource/datasource_digitalocean_droplet should return also information about gateway (and netmask)

Open fiksn opened this issue 5 years ago • 2 comments
trafficstars

I am playing around with Terraform and NixOS. Idea is to use something like https://github.com/tweag/terraform-nixos/tree/master/deploy_nixos w/ DigitalOcean Droplets. Therefore beside IP of the instance I'd also need other networking information (like standard gateway) so I can locally prepare a configuration.nix. This is very specific but I am quite sure that there are other use-cases for obtaining that data after a VM was provisioned. Or is there any reason why that would be a bad idea?

fiksn avatar Nov 21 '20 23:11 fiksn

Now I solved this through (sharing in case anybody else needs it):

data "external" "do_network" {
  program = ["${path.module}/do_network.sh"]

  query = {
    id       = ...
    token = ...
  }
}

and

#!/bin/bash
set -euo pipefail

# requires jq, curl and ipcalc

eval "$(jq -r '@sh "ID=\(.id) TOKEN=\(.token)"')"

function finish {
  rm -rf temp.$$
}
trap finish EXIT

curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" "https://api.digitalocean.com/v2/droplets/$ID" 2>/dev/null > temp.$$
IP4_ADDRESS=$(cat temp.$$ | jq '.droplet.networks.v4[] | select(.type=="public") | .ip_address')
IP4_NETMASK=$(cat temp.$$ | jq '.droplet.networks.v4[] | select(.type=="public") | .netmask')
IP4_GATEWAY=$(cat temp.$$ | jq '.droplet.networks.v4[] | select(.type=="public") | .gateway')
IP4_CIDR=$(ipcalc 1.3.3.7 $IP4_NETMASK -b | grep Netmask | cut -d"=" -f 2 | tr -d " \n")

IP6_ADDRESS=$(cat temp.$$ | jq '.droplet.networks.v6[] | select(.type=="public") | .ip_address')
IP6_CIDR=$(cat temp.$$ | jq '.droplet.networks.v6[] | select(.type=="public") | .netmask')
IP6_GATEWAY=$(cat temp.$$ | jq '.droplet.networks.v6[] | select(.type=="public") | .gateway')

rm -rf temp.$$

jq -n --arg ip4_address "$IP4_ADDRESS" --arg ip4_netmask "$IP4_NETMASK" --arg ip4_gateway "$IP4_GATEWAY" --arg ip4_cidr "$IP4_CIDR" --arg ip6_address "$IP6_ADDRESS" --arg ip6_cidr "$IP6_CIDR" --arg ip6_gateway "$IP6_GATEWAY" \
  '{"ip4_address":$ip4_address, "ip4_netmask":$ip4_netmask, "ip4_gateway":$ip4_gateway, "ip4_cidr":$ip4_cidr, "ip6_adress":$ip6_address, "ip6_cidr":$ip6_cidr, "ip6_gateway":$ip6_gateway}'

which allows me to use something like data.external.do_network.result["ip4_gateway"], but this still feels hackish. As a Terraform noob I am not really sure, is this the desired way to go or should provider return more data?

fiksn avatar Nov 23 '20 00:11 fiksn

As a Terraform noob I am not really sure, is this the desired way to go or should provider return more data?

The better way would be to update the digitialocean_droplet data source and resource to return the networks information that the API appears to already return (going by your shell script). It would just involve some boilerplate Go code to define the schema and then code to take the attributes from the godo client library struct and set it in the Terraform schema.

Do you want to make the changes? I can guide you to the applicable parts of the code.

tdyas avatar Nov 29 '20 20:11 tdyas