terraform output Google Kubernetes cluster inggress load balancer ip

7/24/2018

I've managed to automate kubernetes cluster deployment with terraform. After bringing up cluster terraform also deploys my apps to cluster using provisioning (running .sh script with local-exec). I am also adding ingress to cluster and I need to get the ingress load balancer IP once it created. preferable option is terraform output. The way I am getting it now is running this part of code at the end of my script

IP="$(kubectl get ingress appname --no-headers | awk '{print $3}')"
echo "Load Balancer IP $IP"

However this one has its issues, I need to add sleep before running this command to be sure that the IP is already assigned. and I can't be sure the added sleep time is enough. Actually need smth like these but for my ingress loadbalancer IP

output "google_container_cluster_endpoint" {
  value = "${google_container_cluster.k8s.endpoint}"
}

output "google_container_cluster_master_version" {
  value = "${google_container_cluster.k8s.master_version}"
}
-- Ahnenerbe
google-cloud-platform
kubernetes
kubernetes-ingress

1 Answer

7/28/2018

After a long Saturday, I've end up with a solution to the the problem. I was with almost the same issue, so here is my solution, surely can be improved.

I divided in two parts:

1.- I'll use local-exec to run a script that solves the problem of waiting for a valid IP in the load LoadBalancer 2.-Terraform, using External Data Source calls a "program" that answers in json format. My "program" is a bash script that grabs the IP. As a result, I have my desired data in a variable.

I did it this way cause I didn't know how to debug issues using External Data Source and I was suffering "Stranger things"

First I run the code to wait for a valid IP. Terraform calls the local-exec


provisioner "local-exec" {
  command = "./public-ip.sh"
  interpreter = ["/bin/bash", "-c"]
}

And this is the script I've used


#!/bin/bash
#public-ip.sh
#!/bin/bash
# Exit if any of the intermediate steps fail
set -e

function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

########################
# Grab the Public IP   #
#######################
WaitingTime=0
HaveIP=NO

echo "Let's check that LoadBalancer IP..."
MyPublicIP=$(kubectl get services --all-namespaces| grep LoadBalancer | awk '{print $5}')
valid_ip $MyPublicIP && HaveIP="OK"

until [ "$HaveIP" = "OK" -o "$WaitingTime" -ge 30 ]; do
    echo "sleeeping...."
    sleep 10
    echo "Play it again Sam..."
    MyPublicIP=$(kubectl get services --all-namespaces| grep LoadBalancer | awk '{print $5}')
    #if valid_ip $MyPublicIP; then echo "We got the IP"; HaveIP=YES ;else stat='Still without IP'; fi
    #if valid_ip $MyPublicIP; then HaveIP="OK" ; fi
    valid_ip $MyPublicIP && HaveIP="OK"
    #if valid_ip $MyPublicIP; then HaveIP="OK" ; fi
    WaitingTime=$((WaitingTime+1))
    echo $WaitingTime
done
if [ "$HaveIP" = "OK" ]; then echo  An the public IP is... $MyPublicIP; else echo "WT_ has happened now!!!"; fi

After I know I have the IP ready. I've just needed to grab it. Pay attention to the depends_on that controls I'll grab my data once my resource (google_container_cluster.tests) it's been created, and not whenever he wants. Test it. It's tricky...


data "external" "insights-public-ip" {
  program = ["sh", "test-jq.sh" ]
  depends_on = ["google_container_cluster.tests"]
}

output "insights-public-ip" {
  value = "${data.external.insights-public-ip.result}"
}

And this is test-jq.sh (test cause is the first time I've used :S), the script I'm calling to print out in json format the data.


#!/bin/bash
#test-jq.sh
set -e
MyPublicIP=$(kubectl get services --all-namespaces | grep insights | grep LoadBalancer | awk '{print $5}')
jq -n --arg foobaz "$MyPublicIP" '{"extvar":$foobaz}'

Hope it helps. At least I've resolved my stuff. enter image description here

-- Sergio Oliver
Source: StackOverflow