Skip to content

tkestack/external-dns-tencentcloud-webhook

Repository files navigation

external-dns-tencentcloud-webhook

License Go Report Card

ExternalDNS webhook provider for Tencent Cloud DNS services (DNSPod & PrivateDNS).

Overview

ExternalDNS upstream removed the in-tree tencentcloud provider and recommends the webhook approach. This project implements the webhook protocol as a standalone sidecar.

Service Zone Type Description
DNSPod public Public DNS resolution
PrivateDNS private VPC-scoped internal DNS

Architecture

┌──────────────────────────────── Kubernetes Cluster ──────────────────────────────────┐
│                                                                                      │
│  ┌── external-dns-public ──────────┐      ┌── external-dns-private ──────────────┐   │
│  │                                 │      │                                      │   │
│  │  external-dns ──▶ webhook       │      │  external-dns ──▶ webhook            │   │
│  │                   --zone=public │      │                   --zone=private     │   │
│  │                   --domain=     │      │                   --domain=          │   │
│  │                    example.com  │      │                    internal.example  │   │
│  │                                 │      │                   --vpc-id=vpc-xxx   │   │
│  └───────────────┬─────────────────┘      └───────────────┬──────────────────────┘   │
│                  │                                        │                          │
└──────────────────┼────────────────────────────────────────┼──────────────────────────┘
                   ▼                                        ▼
            DNSPod API                               PrivateDNS API
         (public resolution)                      (VPC-scoped resolution)

Each zone type is a separate Helm release with independent RBAC and credentials. This follows the ExternalDNS recommended pattern — separate instances per zone type for security isolation (least-privilege CAM roles) and operational safety (prevent internal services from modifying public DNS).

Only need one zone type? Just deploy one release. The second is optional.

Installation

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/

Credential mode A: OIDC (recommended)

No static keys needed. Requires:

  • TKE managed cluster with version >= v1.20.6-tke.27 or >= v1.22.5-tke.1
  • OIDC enabled (TKE Console → Cluster → Basic Info → ServiceAccountIssuerDiscovery)

One-command setup (creates CAM role + generates values):

# Public zone
curl -sSL https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/scripts/setup.sh \
  | bash -s -- --auth oidc --zone public --domain example.com

# Private zone
curl -sSL https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/scripts/setup.sh \
  | bash -s -- --auth oidc --zone private --domain internal.example.com

Then install:

helm install external-dns-public external-dns/external-dns \
  -n external-dns --create-namespace \
  -f https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/deploy/helm/values-base.yaml \
  -f values-public.local.yaml

# China mainland: add values-china.yaml for CCR-hosted images
helm install external-dns-public external-dns/external-dns \
  -n external-dns --create-namespace \
  -f https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/deploy/helm/values-base.yaml \
  -f https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/deploy/helm/values-china.yaml \
  -f values-public.local.yaml
Manual values — public zone (without setup script)

Requires CAM role created beforehand. See Prerequisites — OIDC setup for detailed steps.

# values-public.yaml
serviceAccount:
  annotations:
    tke.cloud.tencent.com/role-arn: "qcs::cam::uin/<UIN>:roleName/external-dns-<CLUSTER_ID>-public"
    tke.cloud.tencent.com/audience: "sts.cloud.tencent.com"
    tke.cloud.tencent.com/token-expiration: "86400"

domainFilters:
  - example.com

txtOwnerId: <CLUSTER_ID>-public

provider:
  webhook:
    args:
      - --credential-mode=oidc
      - --zone-type=public
      - --domain-filter=example.com
Manual values — private zone (without setup script)

Requires CAM role with QcloudPrivateDNSFullAccess policy. See Prerequisites — OIDC setup.

# values-private.yaml
serviceAccount:
  annotations:
    tke.cloud.tencent.com/role-arn: "qcs::cam::uin/<UIN>:roleName/external-dns-<CLUSTER_ID>-private"
    tke.cloud.tencent.com/audience: "sts.cloud.tencent.com"
    tke.cloud.tencent.com/token-expiration: "86400"

domainFilters:
  - internal.example.com

txtOwnerId: <CLUSTER_ID>-private

extraArgs:
  - --publish-internal-services

provider:
  webhook:
    args:
      - --credential-mode=oidc
      - --zone-type=private
      - --domain-filter=internal.example.com
      - --vpc-id=vpc-xxxxxxxx

Uses QcloudPrivateDNSFullAccess policy. --publish-internal-services enables ClusterIP Services to create DNS records.

Details: OIDC guide | Prerequisites

Credential mode B: Static credentials

Works on any Kubernetes cluster (TKE, self-managed, EKS, etc). No cluster type or version restriction.

Using the setup script (creates Secret + generates values):

curl -sSL https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/scripts/setup.sh \
  | bash -s -- --auth static --zone public --domain example.com

Or manually:

# 1. Create Secret
kubectl create namespace external-dns
kubectl -n external-dns create secret generic tencentcloud-credentials \
  --from-literal=TENCENTCLOUD_SECRET_ID=<ID> \
  --from-literal=TENCENTCLOUD_SECRET_KEY=<KEY>

# 2. Install
helm install external-dns-public external-dns/external-dns \
  -n external-dns \
  -f https://raw.githubusercontent.com/tkestack/external-dns-tencentcloud-webhook/master/deploy/helm/values-base.yaml \
  -f values-static.yaml
values-static.yaml — public zone
domainFilters:
  - example.com

txtOwnerId: <CLUSTER_ID>-public

provider:
  webhook:
    args:
      - --zone-type=public
      - --domain-filter=example.com
    env:
      - name: TENCENTCLOUD_SECRET_ID
        valueFrom:
          secretKeyRef:
            name: tencentcloud-credentials
            key: TENCENTCLOUD_SECRET_ID
      - name: TENCENTCLOUD_SECRET_KEY
        valueFrom:
          secretKeyRef:
            name: tencentcloud-credentials
            key: TENCENTCLOUD_SECRET_KEY
      - name: TENCENTCLOUD_REGION
        value: "ap-guangzhou"
values-static.yaml — private zone
domainFilters:
  - internal.example.com

txtOwnerId: <CLUSTER_ID>-private

extraArgs:
  - --publish-internal-services

provider:
  webhook:
    args:
      - --zone-type=private
      - --domain-filter=internal.example.com
      - --vpc-id=vpc-xxxxxxxx
    env:
      - name: TENCENTCLOUD_SECRET_ID
        valueFrom:
          secretKeyRef:
            name: tencentcloud-credentials
            key: TENCENTCLOUD_SECRET_ID
      - name: TENCENTCLOUD_SECRET_KEY
        valueFrom:
          secretKeyRef:
            name: tencentcloud-credentials
            key: TENCENTCLOUD_SECRET_KEY
      - name: TENCENTCLOUD_REGION
        value: "ap-guangzhou"

Details: Static credentials guide

Managing both public and private zones

Deploy two separate Helm releases (external-dns-public + external-dns-private), each with its own permissions and values. See public-private-zones guide.

Verify

kubectl -n external-dns get pods
# external-dns-public-xxx   2/2   Running

kubectl -n external-dns logs -l app.kubernetes.io/instance=external-dns-public -c webhook
# "Starting webhook provider server on localhost:8888"

Uninstall

helm uninstall external-dns-public -n external-dns

Configuration

Webhook arg Default Description
--credential-mode static static or oidc (TKE RRSA)
--zone-type public public (DNSPod) or private (PrivateDNS)
--domain-filter Limit to specific domain (repeatable)
--vpc-id VPC ID (required for private zone)
--dry-run false Log changes without applying

Full reference: docs/reference/configuration.md

Guides

Topic Link
Prerequisites (OIDC vs Static) docs/getting-started/prerequisites.md
OIDC mode: how it works + troubleshooting docs/guides/credential-oidc.md
Static mode: config file migration docs/guides/credential-static.md
Managing public + private zones docs/guides/public-private-zones.md
Migrating from in-tree provider docs/guides/migration.md
Provider-specific annotations docs/reference/annotations.md
FAQ external-dns official FAQ

Development

See docs/development/ for building, releasing, and Taskfile reference.

License

Apache License 2.0 — see LICENSE.

About

ExternalDNS webhook provider for Tencent Cloud DNS (DNSPod & PrivateDNS)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors