Skip to content

millstonehq/provider-upjet-tailscale

Repository files navigation

Crossplane Provider Tailscale

License GitHub release

A Crossplane provider for managing Tailscale infrastructure declaratively using Kubernetes-style APIs.

Overview

This provider enables you to manage Tailscale resources through Crossplane, bringing GitOps-style infrastructure management to your Tailscale tailnet.

Supported Resources

  • ACL - Manage tailnet access control lists with HuJSON support
  • DNS Nameservers - Configure custom DNS nameservers for your tailnet
  • Tailnet Keys - Generate authentication keys with tags and policies
  • Device Tags - Assign tags to devices in your tailnet
  • Device Authorization - Approve or manage device authorizations

Installation

Prerequisites

  • Kubernetes cluster with Crossplane installed (v1.14.0+)
  • Tailscale account with API access
  • Crossplane 2.0+ installed in your cluster

Install the Provider

# Create the provider
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-tailscale
spec:
  package: ghcr.io/millstonehq/provider-tailscale:latest
EOF

# Verify installation
kubectl get providers

Configure Authentication

  1. Create a Tailscale API Key

    Visit the Tailscale Admin Console and create a new API key with appropriate permissions.

  2. Create a Kubernetes Secret

    kubectl create secret generic tailscale-creds \
      --namespace crossplane-system \
      --from-literal=api_key='tskey-api-xxxxx'
  3. Create a ProviderConfig

    kubectl apply -f - <<EOF
    apiVersion: tailscale.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
      name: default
    spec:
      credentials:
        source: Secret
        secretRef:
          name: tailscale-creds
          namespace: crossplane-system
          key: api_key
    EOF

Usage Examples

ACL Management

apiVersion: acl.tailscale.upbound.io/v1alpha1
kind: ACL
metadata:
  name: production-acl
spec:
  forProvider:
    acl: |
      {
        "groups": {
          "group:admin": ["admin@example.com"],
        },
        "acls": [
          {
            "action": "accept",
            "src": ["group:admin"],
            "dst": ["*:*"],
          },
        ],
      }
  providerConfigRef:
    name: default

Generate Auth Keys

apiVersion: tailnetkey.tailscale.upbound.io/v1alpha1
kind: Key
metadata:
  name: k8s-node-key
spec:
  forProvider:
    reusable: true
    preauthorized: true
    tags:
      - "tag:k8s"
      - "tag:production"
  writeConnectionSecretToRef:
    name: tailscale-k8s-key
    namespace: default
  providerConfigRef:
    name: default

Configure DNS Nameservers

apiVersion: dns.tailscale.upbound.io/v1alpha1
kind: Nameservers
metadata:
  name: custom-dns
spec:
  forProvider:
    nameservers:
      - "1.1.1.1"
      - "8.8.8.8"
  providerConfigRef:
    name: default

Device Tag Management

apiVersion: device.tailscale.upbound.io/v1alpha1
kind: Tags
metadata:
  name: web-server-tags
spec:
  forProvider:
    deviceId: "12345678901234567"
    tags:
      - "tag:production"
      - "tag:webserver"
  providerConfigRef:
    name: default

Device Authorization

apiVersion: device.tailscale.upbound.io/v1alpha1
kind: Authorization
metadata:
  name: approve-device
spec:
  forProvider:
    deviceId: "12345678901234567"
    authorized: true
  providerConfigRef:
    name: default

Development

Building from Source

This provider uses Earthly for building and testing.

# Generate code
earthly +generate

# Build the provider
earthly +build

# Run tests
earthly +test

# Test with examples
earthly +test-examples

# Run all tests (unit + examples)
earthly +test-all

# Build and push images (requires authentication)
earthly --push +push

Local Development

# Build provider package locally
earthly +package-local

# Install in your cluster
kubectl apply -f examples/providerconfig/

Architecture

This provider is built using:

  • Upjet v2.0.0 - Code generation framework for Terraform-based Crossplane providers
  • Crossplane Runtime v2.0.0 - Core Crossplane functionality
  • Terraform Provider Tailscale v0.18.0 - Underlying Terraform provider

Authentication Methods

The provider supports two authentication methods:

  1. API Key (Recommended for simplicity)

    stringData:
      api_key: "tskey-api-xxxxx"
  2. OAuth Credentials (For programmatic access)

    stringData:
      oauth_client_id: "xxxxx"
      oauth_client_secret: "tskey-client-xxxxx"

Community & Contributing

We welcome contributions from the community! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated.

How to Contribute

  1. Fork the repository on GitHub
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes and commit them (git commit -m 'feat: add amazing feature')
  4. Push to your branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please read our CONTRIBUTING.md for detailed guidelines on:

  • Development setup and building from source
  • Code style and conventions
  • Testing requirements
  • PR submission process

Getting Help

Code of Conduct

This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Copyright 2025 Millstone Partners, LLC

Support

For issues and questions:

References

Releases

No releases published

Packages