Introducing PostScale -- email API for transactional, inbound, and masked addresses. PostScale

    Managing DNS with DNSControl

    Learn how to manage your DNS zones and records as code using DNSControl with the DNScale provider. Define your entire DNS configuration in JavaScript.

    DNSControl lets you manage DNS with a JavaScript-based configuration file. You define your zones and records in dnsconfig.js, preview changes with dnscontrol preview, and apply them with dnscontrol push. The DNScale provider integrates directly with the DNScale API, giving you full control over your DNS infrastructure as code.

    Prerequisites

    Before you begin, ensure you have:

    1. DNSControl installed (version 4.0 or later) - Install DNSControl
    2. A DNScale account with an API key - Get your API key
    3. Basic familiarity with JavaScript syntax

    Setup

    DNSControl uses a creds.json file for provider credentials. Create this file in your project directory:

    {
      "dnscale": {
        "TYPE": "DNSCALE",
        "api_key": "your-api-key-here"
      }
    }

    The provider connects to https://api.dnscale.eu/v1 by default. To use a custom API endpoint, add api_url:

    {
      "dnscale": {
        "TYPE": "DNSCALE",
        "api_key": "your-api-key-here",
        "api_url": "https://custom-api.example.com/v1"
      }
    }

    Keep creds.json out of version control. Add it to your .gitignore:

    echo "creds.json" >> .gitignore

    Creating Your First Zone

    Create a dnsconfig.js file with a basic zone definition:

    var REG_NONE = NewRegistrar("none");
    var DSP_DNSCALE = NewDnsProvider("dnscale");
     
    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", "192.0.2.1"),
      A("www", "192.0.2.1")
    );

    This configuration:

    • Declares the DNScale provider using credentials from creds.json
    • Creates a zone for example.com
    • Adds two A records: one at the apex (@) and one for www

    When you run dnscontrol push, DNScale automatically creates the zone if it doesn't exist yet.

    Managing DNS Records

    A Records

    Point hostnames to IPv4 addresses:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", "192.0.2.1"),
      A("www", "192.0.2.1"),
      A("api", "192.0.2.10", TTL(300))
    );

    AAAA Records

    Add IPv6 support:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      AAAA("@", "2001:db8::1"),
      AAAA("www", "2001:db8::1")
    );

    CNAME Records

    Create aliases for subdomains:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      CNAME("blog", "example.github.io."),
      CNAME("docs", "readthedocs.io.")
    );

    ALIAS Records

    Use ALIAS for apex-level CNAME-like behavior:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      ALIAS("@", "loadbalancer.example.net.")
    );

    MX Records

    Configure email delivery:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      MX("@", 10, "mail.example.com."),
      MX("@", 20, "mail2.example.com.")
    );

    TXT Records

    Add SPF, DKIM, or verification records:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      TXT("@", "v=spf1 include:_spf.google.com ~all"),
      TXT("@", "google-site-verification=abc123"),
      TXT("_dmarc", "v=DMARC1; p=reject; rua=mailto:dmarc@example.com")
    );

    CAA Records

    Control which certificate authorities can issue certificates for your domain:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      CAA("@", "issue", "letsencrypt.org"),
      CAA("@", "issuewild", "letsencrypt.org"),
      CAA("@", "iodef", "mailto:security@example.com")
    );

    SRV Records

    Define service locations:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      SRV("_sip._tcp", 10, 60, 5060, "sip.example.com.")
    );

    PTR Records

    Create reverse DNS entries:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      PTR("1", "server.example.com.")
    );

    SSHFP Records

    Publish SSH host key fingerprints:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      SSHFP("@", 1, 1, "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3")
    );

    TLSA Records

    Associate TLS certificates with domain names:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      TLSA("_443._tcp", 3, 1, 1, "abc123def456...")
    );

    HTTPS and SVCB Records

    Configure service binding for modern HTTPS connections:

    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      HTTPS("@", 1, ".", "alpn=h2,h3"),
      SVCB("_dns.resolver", 1, "dns.example.com.", "alpn=dot")
    );

    Advanced Configuration

    Multiple Domains

    Manage several domains in one configuration file:

    var REG_NONE = NewRegistrar("none");
    var DSP_DNSCALE = NewDnsProvider("dnscale");
     
    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", "192.0.2.1"),
      A("www", "192.0.2.1"),
      MX("@", 10, "mail.example.com.")
    );
     
    D("example.org", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", "192.0.2.2"),
      CNAME("www", "example.org.")
    );
     
    D("example.net", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", "192.0.2.3"),
      CNAME("www", "example.net.")
    );

    Using Variables

    Since dnsconfig.js is JavaScript, you can use variables to reduce repetition:

    var REG_NONE = NewRegistrar("none");
    var DSP_DNSCALE = NewDnsProvider("dnscale");
     
    var WEBSERVER_IP = "192.0.2.1";
    var MAIL_SERVERS = [
      MX("@", 10, "mx1.mailprovider.com."),
      MX("@", 20, "mx2.mailprovider.com.")
    ];
    var SPF = TXT("@", "v=spf1 include:_spf.mailprovider.com ~all");
     
    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", WEBSERVER_IP),
      A("www", WEBSERVER_IP),
      MAIL_SERVERS,
      SPF
    );
     
    D("example.org", REG_NONE, DnsProvider(DSP_DNSCALE),
      A("@", WEBSERVER_IP),
      A("www", WEBSERVER_IP),
      MAIL_SERVERS,
      SPF
    );

    Macros with Functions

    Create reusable record patterns using JavaScript functions:

    function WEBSITE(ip) {
      return [
        A("@", ip),
        A("www", ip),
        AAAA("@", "2001:db8::1"),
        AAAA("www", "2001:db8::1")
      ];
    }
     
    function GOOGLE_WORKSPACE() {
      return [
        MX("@", 1, "aspmx.l.google.com."),
        MX("@", 5, "alt1.aspmx.l.google.com."),
        MX("@", 5, "alt2.aspmx.l.google.com."),
        TXT("@", "v=spf1 include:_spf.google.com ~all")
      ];
    }
     
    D("example.com", REG_NONE, DnsProvider(DSP_DNSCALE),
      WEBSITE("192.0.2.1"),
      GOOGLE_WORKSPACE()
    );

    Preview and Push Workflow

    DNSControl uses a two-step workflow: preview your changes first, then apply them.

    Preview Changes

    dnscontrol preview

    This connects to the DNScale API, compares your dnsconfig.js with the current live records, and shows what would change:

    ******************** Domain: example.com
    1 correction (dnscale)
    #1: CREATE A www.example.com 192.0.2.1 ttl=3600

    Apply Changes

    Once you're satisfied with the preview, apply the changes:

    dnscontrol push
    ******************** Domain: example.com
    1 correction (dnscale)
    #1: CREATE A www.example.com 192.0.2.1 ttl=3600
    Done. 1 correction.

    Best Practices

    Version Control Your Configuration

    Keep dnsconfig.js in Git to track every DNS change:

    git init
    echo "creds.json" >> .gitignore
    git add dnsconfig.js .gitignore
    git commit -m "Initial DNS configuration"

    Always Preview Before Pushing

    Run dnscontrol preview before every dnscontrol push. This catches mistakes before they affect live DNS.

    Use CI/CD for Automated Deployments

    Add DNSControl to your CI/CD pipeline. Run preview on pull requests and push on merge to main:

    # .github/workflows/dns.yml
    name: DNS
    on:
      pull_request:
        paths: ["dnsconfig.js"]
      push:
        branches: [main]
        paths: ["dnsconfig.js"]
     
    jobs:
      dns:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Install DNSControl
            run: |
              curl -sL https://github.com/StackExchange/dnscontrol/releases/latest/download/dnscontrol-Linux -o dnscontrol
              chmod +x dnscontrol
          - name: Preview
            if: github.event_name == 'pull_request'
            run: ./dnscontrol preview
            env:
              DNSCALE_API_KEY: ${{ secrets.DNSCALE_API_KEY }}
          - name: Push
            if: github.ref == 'refs/heads/main'
            run: ./dnscontrol push
            env:
              DNSCALE_API_KEY: ${{ secrets.DNSCALE_API_KEY }}

    Keep Credentials Secure

    Never commit creds.json. Use environment variables or a secrets manager in CI/CD.

    Complete Example

    Here's a full dnsconfig.js for a typical website with email:

    var REG_NONE = NewRegistrar("none");
    var DSP_DNSCALE = NewDnsProvider("dnscale");
     
    var SERVER_IP = "203.0.113.50";
     
    D("mywebsite.com", REG_NONE, DnsProvider(DSP_DNSCALE),
     
      // Website
      A("@", SERVER_IP),
      AAAA("@", "2001:db8::50"),
      CNAME("www", "mywebsite.com."),
     
      // API subdomain
      A("api", "203.0.113.51", TTL(300)),
     
      // Email (Google Workspace)
      MX("@", 1, "aspmx.l.google.com."),
      MX("@", 5, "alt1.aspmx.l.google.com."),
      MX("@", 5, "alt2.aspmx.l.google.com."),
      MX("@", 10, "alt3.aspmx.l.google.com."),
      MX("@", 10, "alt4.aspmx.l.google.com."),
     
      // Email security
      TXT("@", "v=spf1 include:_spf.google.com ~all"),
      TXT("_dmarc", "v=DMARC1; p=reject; rua=mailto:dmarc@mywebsite.com"),
     
      // Certificate authority authorization
      CAA("@", "issue", "letsencrypt.org"),
      CAA("@", "issuewild", "letsencrypt.org"),
     
      // HTTPS service binding
      HTTPS("@", 1, ".", "alpn=h2,h3")
    );

    Next Steps

    Conclusion

    DNSControl brings DNS-as-code to your workflow with a straightforward JavaScript configuration. Combined with the DNScale provider, you get version-controlled DNS changes, safe preview-before-push workflows, and the ability to manage multiple domains from a single file. Whether you're managing one domain or hundreds, DNSControl provides the tooling to do it reliably and at scale.

    dnscontrol push your DNS today.