ryantiffany dot com

Expose VPC services to your local network with Custom Resolvers and Tailscale

In a previous post I showed you how to deploy a Tailscale subnet router in an IBM Cloud VPC and and advertise multiple VPC subnets to your larger tailscale network. In this post we will look at another use case that includes using the DNS Services offering as well as Custom Resolvers to allow you to access services running in your VPC from your local network using their Fully Qualified Domain Name (FQDN).

In this demo environment we will deploy a VPC, provision a subnet router instance, and then deploy some sample services in the VPC. We will then use the IBM Cloud DNS Services to create a custom resolver that will resolve the FQDN of these services to the private IP address of our instances. We will then connect to the subnet router using Tailscale and test the resolution of the FQDN.

Diagram

Here is a hgh level overview of the solution:

Diagram of Tailscale deployment

Here is a closer look at the docker host that will run our sample services and expose them via Traefik:

Diagram of Traefik + Docker deployment

Pre-reqs

Getting started

Clone repository and configure terraform variables

The first step is to clone the repository and configure the terraform variables.

git clone https://github.com/cloud-design-dev/ibmcloud-ts-router-pdns.git
cd ibmcloud-vpc-ts-router

Copy the example terraform variables file and update the values with your own. The example file only contains variables without defaults. To see the full list of supported options visit the repositories README.

cp tfvars-template terraform.tfvars

Initialize, Plan and Apply the Terraform configuration

Once you have the required variables set, you can initialize the terraform configuration and create a plan for the deployment.

terraform init
terraform plan -out=plan.out

If no errors are returned, you can apply the plan to create the VPCs, subnets, and compute instances.

terraform apply plan.out

When the provisioning completes, you should see the output of the plan, including the private IP addresses of the compute hosts, the advertised subnets, and our custom resolvers.

Apply complete! Resources: 38 added, 0 changed, 0 destroyed.

custom_resolver_ips = tolist([
  "10.250.0.69",
  "10.250.64.4",
])
lab_fqdns = [
  "whoami.ygdg-internal.lab",
  "tools.ygdg-internal.lab",
  "requests.ygdg-internal.lab",
  "dashboard.ygdg-internal.lab",
]
tailscale_instance_ip = "10.250.0.4"
workload_instance_ip = "10.250.0.68"
zone1_subnet_cidr = "10.250.0.64/26"
zone2_subnet_cidr = "10.250.64.0/26"

Approve the advertised subnets in the Tailscale admin console

By default the subnet router will not advertise any of the subnets until they are approved in the Tailscale admin console. From the admin console, navigate to the Machines tab and click the subnet router instance name. On the machine details page you should see the subnets that are available to be advertised.

Subnets awaiting advertisement approval

Under Approved click Edit and select the subnets you want to advertise and click Save.

Approving the subnets

Connect to Tailscale and check connectivity

Once the subnets are approved, you can start the Tailscale app on your local machine and set the local DNS resolvers to the custom resolvers that were created in the VPC. You can find the IP addresses of the custom resolvers in the terraform output. If you happen to be using a Mac, you can set the custom resolvers in the Network settings or via the command line with the networksetup command:

networksetup -setdnsservers Ethernet 10.250.0.69 10.250.64.4

With the resolvers set, we can now start testing connectivity to our deployed services. Take one of the FQDNs from the terraform output and try to connect to it.

curl "http://$(terraform output --json | jq -r '.lab_fqdns.value[0]')"

% curl http://whoami.ygdg-internal.lab                                                                                                                                                                    24-09-13 - 11:30:46
Hostname: 307a35892c5c
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.5
RemoteAddr: 172.18.0.2:49386
GET / HTTP/1.1
Host: whoami.ygdg-internal.lab
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.250.0.4
X-Forwarded-Host: whoami.ygdg-internal.lab
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 71cfe6245938
X-Real-Ip: 10.250.0.4

Browser test

Clean up

To remove the resources created by the terraform configuration, you can run the destroy command.

terraform destroy

Conclusion

In this example we have deployed a Tailscale subnet router in an IBM Cloud VPC to expose private DNS services to our Tailscale network. We also created custom resolvers in the private DNS zone that allow us to connect to our private services using the FQDNs we have defined in the private DNS zone from our local machine.

#dns #ibmcloud #tailscale