One place for hosting & domains

      How To Deploy and Manage Your DNS using OctoDNS on Ubuntu 18.04


      The author selected the Electronic Frontier Foundation to receive a donation as part of the Write for DOnations program.

      Introduction

      OctoDNS is an infrastructure-as-code tool that allows you to deploy and manage your DNS zones using standard software development principles, including version control, testing, and automated deployment. OctoDNS was created by GitHub and is written in Python.

      Using OctoDNS eliminates many of the pitfalls of manual DNS management, as zone files are stored in a structured format (YAML). This allows you to deploy zones to multiple DNS providers simultaneously, identify syntax errors, and push out your DNS configuration automatically, reducing the risk of human error. Another common usage of OctoDNS is to synchronize your DNS configuration between different providers, such as a testing and production system, or between live and failover environments.

      OctoDNS is similar to DNSControl, which is an equivalent tool created by Stack Exchange and written in Go. Unlike OctoDNS, DNSControl uses a JavaScript-based configuration language for defining DNS zones, which allows you to use advanced programmatic features such as loops to specify multiple similar records within the same zone. The article How to Deploy and Manage Your DNS Using DNSControl on Ubuntu 18.04 covers the basic setup and configuration of DNSControl.

      In this tutorial, you’ll install and configure OctoDNS, create a basic DNS configuration, and begin deploying DNS records to a live provider. As part of this tutorial, we will use DigitalOcean as the example DNS provider. If you wish to use a different provider, the setup is very similar. When you’re finished, you’ll be able to manage and test your DNS configuration in a safe, offline environment, and then automatically deploy it to production.

      Prerequisites

      Before you begin this guide you’ll need the following:

      • One Ubuntu 18.04 server set up by following the Initial Server Setup with Ubuntu 18.04, including a sudo non-root user and enabled firewall to block non-essential ports. your-server-ipv4-address and your-server-ipv6-address refer to the IP addresses of the server where you’re hosting your website or domain.
      • A fully registered domain name with DNS hosted by a supported provider. This tutorial will use your-domain throughout and DigitalOcean as the service provider.
      • A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.

      Once you have these ready, log in to your server as your non-root user to begin.

      Step 1 — Installing OctoDNS

      OctoDNS is distributed as a Python pip package, and runs in a Python Virtual Environment (virtualenv), so you’ll start this step by installing the packages required for this. A virtualenv is an isolated Python environment that can have its own libraries and configuration, separate from the main system-wide Python installation. Python and virtualenv are available within Ubuntu’s default software repositories, making it possible to install using conventional package management tools.

      Begin by updating the local package index to reflect any new upstream changes:

      Then, install the python and virtualenv packages:

      • sudo apt install python virtualenv

      After confirming the installation, apt will download and install Python, virtualenv, and all of their required dependencies.

      Next, you'll create the required directories for OctoDNS, where your DNS and program configuration will be stored. Start by creating the ~/octodns and ~/octodns/config directories:

      • mkdir ~/octodns ~/octodns/config

      Now move into ~/octodns:

      Next, you need to create the Python Virtual Environment—an isolated Python environment with its own libraries and configuration to run OctoDNS in:

      Activate your environment with the following command:

      This will output something similar to the following:

      Output

      Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/user/octodns/env/bin/python2 Also creating executable in /home/user/octodns/env/bin/python Installing setuptools, pkg_resources, pip, wheel...done.

      Your Bash shell prompt will now also be prefixed with the name of the virtual environment. This shows that you are currently operating within the virtualenv:

      (env) user@digitalocean:~/octodns$
      

      If you wish to exit the virtualenv, you can use the deactivate command at any time. However, you should stay in your virtualenv to continue with this tutorial.

      Now that you've installed and configured Python and virtualenv, you can install OctoDNS. OctoDNS is distributed as a Python pip package, which is the standard package-management tool for Python packages and libraries.

      You can install the OctoDNS pip package using the following command within your virtualenv:

      Once this is complete, you can check the installed version to make sure that everything is working:

      Your output will look similar to the following:

      Output

      octoDNS 0.9.6

      If you see a octodns-sync: command not found error, double-check that you're still inside your virtualenv.

      Now that you've installed OctoDNS, you can create the required configuration files to connect OctoDNS to your DNS provider to allow it to make changes to your DNS records.

      Step 2 — Configuring OctoDNS

      In this step, you'll create the required configuration files for OctoDNS, and connect it to your DNS provider so that it can begin to make live changes to your DNS records.

      Note: This tutorial will focus on the initial setup of OctoDNS; however for production use it is recommended to store your OctoDNS configuration in a version control system (VCS) such as Git. The advantages of this include full version control, integration with CI/CD for testing, seamlessly rolling-back deployments, and so on.

      Firstly, you need to configure the config.yaml file, which defines the DNS zones for OctoDNS to manage, and allows it to authenticate to your DNS provider and make changes.

      The format of config.yaml differs slightly depending on the DNS provider that you are using. Please see the Supported Providers list in the official OctoDNS documentation to find the configuration for your own provider. When viewing this hyperlink, the configuration details are presented as a code comment in the actual Python code for your provider, which is linked in the 'Provider' column of the table. Once you have found the Python code for your provider, such as cloudflare.py or route53.py, the relevant code comment can be found directly under the class ProviderNameProvider. For example:

      Excerpt of octodns/provider/route53.py

      class Route53Provider(BaseProvider):
          '''
          AWS Route53 Provider
          route53:
              class: octodns.provider.route53.Route53Provider
              # The AWS access key id
              access_key_id:
              # The AWS secret access key
              secret_access_key:
              # The AWS session token (optional)
              # Only needed if using temporary security credentials
              session_token:
      

      Move into the ~/octodns/config directory:

      Then create and open config.yaml for editing:

      Add the sample config.yaml configuration for your DNS provider to the file. If you're using DigitalOcean as your DNS provider, you can use the following:

      ~/octodns/config/config.yaml

      ---
      providers:
        config:
          class: octodns.provider.yaml.YamlProvider
          directory: ./config
          default_ttl: 300
          enforce_order: True
        digitalocean:
          class: octodns.provider.digitalocean.DigitalOceanProvider
          token: your-digitalocean-oauth-token
      
      zones:
        your-domain.:
          sources:
            - config
          targets:
            - digitalocean
      

      This file tells OctoDNS which DNS providers you want it to connect to, and which DNS zones it should manage for those providers.

      You'll need to provide some form of authentication for your DNS provider. This is usually an API key or OAuth token.

      If you do not wish to store your access token in plain text in the configuration file, you can instead pass it as an environment variable when the program runs. To do this, you should use the following token: line instead in config.yaml:

      ~/octodns/config/config.yaml

      token: env/DIGITALOCEAN_OAUTH_TOKEN
      

      Then, before running OctoDNS, set the relevant environment variable to your access token, and OctoDNS will read it from there when run:

      • export DIGITALOCEAN_OAUTH_TOKEN=your-digitalocean-oauth-token

      Warning: This token will grant access to your DNS provider account, so you should protect it as you would a password. Also, ensure that if you're using a version control system, either the file containing the token is excluded (e.g. using .gitignore), or is securely encrypted in some way.

      If you're using DigitalOcean as your DNS provider, you can use the required OAuth token in your DigitalOcean account settings that you generated as part of the prerequisites.

      If you have multiple different DNS providers—for example, for multiple domain names, or delegated DNS zones—you can define these all in the same config.yaml file.

      You've set up the initial OctoDNS configuration file to allow the program to authenticate to your DNS provider and make changes. Next you'll create the configuration for your DNS zones.

      Step 3 — Creating a DNS Configuration File

      In this step, you'll create an initial DNS configuration file, which will contain the DNS records for your domain name or delegated DNS zone.

      Each DNS zone that you want to manage using OctoDNS has its own file, for example your-domain.yaml. In this file, the DNS records for the zone are defined using YAML.

      To begin, move into the ~/octodns/config directory:

      Then create and open your-domain.yaml for editing:

      Add the following sample configuration to the file:

      ~/octodns/config/your-domain.yaml

      ---
      '':
        - type: A
          value: your-server-ipv4-address
      
      www:
        - type: A
          value: your-server-ipv4-address
      

      This sample file defines a DNS zone for your-domain with two A records, pointing to the IPv4 address that you're hosting your domain or website on. One A record is for the root domain (e.g. your-domain), and the other is for the www subdomain (e.g. www.your-domain).

      Once complete, save and close the file.

      You've set up a basic DNS zone configuration file for OctoDNS, with two basic A records pointing to the IPv4 address of your domain or website. Next, you'll expand the file with some useful DNS records.

      Step 4 — Populating Your DNS Configuration File

      Next, you can populate the DNS configuration file with a practical set of DNS records for your website or service, using the YAML structured configuration language.

      Unlike traditional BIND zone files, where DNS records are written in a raw, line-by-line format, DNS records within OctoDNS are defined as YAML keys and subkeys with a number of associated values, as shown briefly in Step 3.

      The top-level key is usually the 'name', which is essentially the record identifier. www, subdomain1, and mail are all examples of DNS 'name'. In OctoDNS, there are two special-use names, which are '', for the root record (usually referred to as @), and '*', for wildcard records. A required value of each key (DNS record) is type. This defines which type of DNS record you are defining within that YAML top-level key. A type exists for each of the standard DNS record types, including A, AAAA, MX, TXT, NS, CNAME, and so on. A full list of available record types is available in the Records section of the OctoDNS documentation.

      The values for your DNS records are defined either directly as values to the top-level keys (if you only have one value), or as a list (if you have multiple values, e.g. multiple IP addresses or MX addresses).

      For example, to define a single value, you could use the following configuration:

      ~/octodns/config/your-domain.yaml

      'www':
        type: A
        value: 203.0.113.1
      

      Alternatively, to define multiple values for a single record:

      ~/octodns/config/your-domain.yaml

      'www':
        type: A
        values:
        - 203.0.113.1
        - 203.0.113.2
      

      The syntax for setting DNS records varies slightly for each record type. Following are some examples for the most common record types:

      A records:

      Purpose: To point to an IPv4 address.

      Syntax:

      'name':
        type: A
        value: ipv4-address
      

      Example:

      'www':
        type: A
        value: your-server-ipv4-address
      

      AAAA records:

      Purpose: To point to an IPv6 address.

      Syntax:

      'name':
        type: AAAA
        value: ipv6-address
      

      Example:

      'www':
        type: AAAA
        value: your-server-ipv6-address
      

      CNAME records:

      Purpose: To make your domain/subdomain an alias of another.

      Syntax:

      'name':
        type: CNAME
        value: fully-qualified-domain-name
      

      Example:

      'www':
        type: CNAME
        value: www.example.org
      

      MX records:

      Purpose: To direct email to specific servers/addresses.

      Syntax:

      'name':
        type: MX
        value:
          exchange: mail-server
          preference: priority-value
      

      Note that a trailing . must be included if there are any dots in the MX value.

      Example:

      '':
        type: MX
        value:
          exchange: mail.your-domain.
          preference: 10
      

      TXT records:

      Purpose: To add arbitrary plain text, often used for configurations without their own dedicated record type.

      Syntax:

      'name':
        type: TXT
        value: content
      

      Example:

      '':
        type: TXT
        value: This is a TXT record.
      

      In order to begin adding DNS records for your domain or delegated DNS zone, edit your DNS configuration file:

      • cd ~/octodns/config
      • nano your-domain.yaml

      Next, you can begin populating your DNS zone using the syntax described in the previous list, as well as the Records section of the official OctoDNS documentation.

      For reference, the code block here contains a full sample configuration for an initial DNS setup:

      ~/octodns/config/your-domain.yaml

      ---
      '':
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      
        - type: MX
          value:
            exchange: mail.your-domain.
            preference: 10
      
        - type: TXT
          value: v=spf1 -all
      
      _dmarc:
        type: TXT
        value: v=DMARC1; p=reject; rua=mailto:abuse@your-domain; aspf=s; adkim=s;
      
      mail:
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      
      www:
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      

      Once you have completed your initial DNS configuration, save and close the file.

      In this step, you set up the initial DNS configuration file, containing your DNS records. Next, you will test the configuration and deploy it.

      Step 5 — Testing and Deploying Your DNS Configuration

      In this step, you will run a local syntax check on your DNS configuration, and then deploy the changes to the live DNS server/provider.

      Firstly, move into your octodns directory:

      Double check that you're still operating within your Python virtualenv by looking for the name of it before your Bash prompt:

      (env) user@digitalocean:~/octodns$
      

      Next, use the octodns-validate command to check the syntax of your configuration file(s). You'll need to specify the path to your configuration file:

      • octodns-validate --config=./config/config.yaml

      If the YAML syntax of your DNS configuration file is correct, OctoDNS will return with no output.

      If you see an error or warning in your output, OctoDNS will provide details on what and where the error is located within your YAML file.

      Next, you can perform a dry-run push of the DNS configuration, which will output which changes will be made, without actually making them:

      • octodns-sync --config=./config/config.yaml

      This should produce an output similar to the following:

      Output

      ******************************************************************************** * your-domain. ******************************************************************************** * digitalocean (DigitalOceanProvider) * Create <ARecord A 300, mail.your-domain., ['your-server-ipv4-address']> (config) * Create <AaaaRecord AAAA 300, mail.your-domain., ['your-server-ipv6-address']> (config) * Create <TxtRecord TXT 300, your-domain., ['v=spf1 -all']> (config) * Create <AaaaRecord AAAA 300, your-domain., ['your-server-ipv6-address']> (config) * Create <ARecord A 300, your-domain., ['your-server-ipv4-address']> (config) * Create <ARecord A 300, www.your-domain., ['your-server-ipv4-address']> (config) * Create <MxRecord MX 300, your-domain., [''10 mail.your-domain.'']> (config) * Create <TxtRecord TXT 300, _dmarc.your-domain., ['v=DMARC1; p=reject; rua=mailto:abuse@your-domain; aspf=s; adkim=s;']> (config) * Create <AaaaRecord AAAA 300, www.your-domain., ['your-server-ipv6-address']> (config) * Summary: Creates=9, Updates=0, Deletes=0, Existing Records=2 ********************************************************************************

      Warning: The next command will make live changes to your DNS records and possibly other settings. Please ensure that you are prepared for this, including taking a backup of your existing DNS configuration, as well as ensuring that you have the means to roll back if needed.

      Finally, you can push out the changes to your live DNS provider:

      • octodns-sync --config=./config/config.yaml --doit

      Note: In some cases, OctoDNS will refuse to push changes if it is making a significant number of adjustments. This is an automatic protection feature to prevent accidental misconfigurations. If you encounter this refusal, you can re-run octodns-sync using the --force option, but please ensure you are ready to do so.

      You'll see an output like the dry-run earlier in this step, but with the addition of something similar to the following:

      Output

      2019-07-07T23:17:27 INFO DigitalOceanProvider[digitalocean] apply: making changes 2019-07-07T23:17:30 INFO Manager sync: 9 total changes

      Now, if you check the DNS settings for your domain in the DigitalOcean control panel, you'll see the changes.

      A screenshot of the DigitalOcean control panel, showing some of the DNS changes that OctoDNS has made.

      You can also check the record creation by running a DNS query for your domain/delegated zone. You'll see that the records have been updated accordingly:

      You'll see output showing the IP address and relevant DNS record from your zone that was deployed using OctoDNS. DNS records can take some time to propagate, so you may need to wait and run this command again.

      In this final step, you ran a local syntax check of the DNS configuration file, then deployed it to your live DNS provider, and tested that the changes were made successfully.

      Conclusion

      In this article you set up OctoDNS and deployed a DNS configuration to a live provider. Now you can manage and test your DNS configuration changes in a safe, offline environment before deploying them to production.

      If you wish to explore this subject further, OctoDNS is designed to be integrated into your CI/CD pipeline, allowing you to run in-depth tests and have more control over your deployment to production. You could also look into integrating OctoDNS into your infrastructure build/deployment processes, allowing you to deploy servers and add them to DNS completely automatically.

      If you wish to go further with OctoDNS, the following DigitalOcean articles provide some interesting next steps to help integrate OctoDNS into your change management and infrastructure deployment workflows:



      Source link

      How To Deploy and Manage Your DNS using DNSControl on Ubuntu 18.04


      The author selected the Electronic Frontier Foundation Inc to receive a donation as part of the Write for DOnations program.

      Introduction

      DNSControl is an infrastructure-as-code tool that allows you to deploy and manage your DNS zones using standard software development principles, including version control, testing, and automated deployment. DNSControl was created by Stack Exchange and is written in Go.

      Using DNSControl eliminates many of the pitfalls of manual DNS management, as zone files are stored in a programmable format. This allows you to deploy zones to multiple DNS providers simultaneously, identify syntax errors, and push out your DNS configuration automatically, reducing the risk of human error. Another common usage of DNSControl is to quickly migrate your DNS to a different provider; for example, in the event of a DDoS attack or system outage.

      In this tutorial, you’ll install and configure DNSControl, create a basic DNS configuration, and begin deploying DNS records to a live provider. As part of this tutorial, we will use DigitalOcean as the example DNS provider. If you wish to use a different provider, the setup is very similar. When you’re finished, you’ll be able to manage and test your DNS configuration in a safe, offline environment, and then automatically deploy it to production.

      Prerequisites

      Before you begin this guide you’ll need the following:

      • One Ubuntu 18.04 server set up by following the Initial Server Setup with Ubuntu 18.04, including a sudo non-root user and enabled firewall to block non-essential ports. your-server-ip refers to the IP address of the server where you’re hosting your website or domain.
      • A fully registered domain name with DNS hosted by a supported provider. This tutorial will use example.com throughout and DigitalOcean as the service provider.
      • A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.

      Once you have these ready, log in to your server as your non-root user to begin.

      Step 1 — Installing DNSControl

      DNSControl is written in Go, so you’ll start this step by installing Go to your server and setting your GOPATH.

      Go is available within Ubuntu’s default software repositories, making it possible to install using conventional package management tools.

      Begin by updating the local package index to reflect any new upstream changes:

      Then, install the golang-go package:

      • sudo apt install golang-go

      After confirming the installation, apt will download and install Go and all of its required dependencies.

      Next, you'll configure the required path environment variables for Go. If you would like to know more about this, you can read this tutorial on Understanding the GOPATH. Start by editing the ~/.profile file:

      Add the following lines to the very end of your file:

      ~/.profile

      ...
      export GOPATH="$HOME/go"
      export PATH="$PATH:$GOPATH/bin"
      

      Once you have added these lines to the bottom of the file, save and close it. Then reload your profile by either logging out and back in, or sourcing the file again:

      Now you've installed and configured Go, you can install DNSControl.

      The go get command can be used to fetch a copy of the code, automatically compile it and install it into your Go directory:

      • go get github.com/StackExchange/dnscontrol

      Once this is complete, you can check the installed version to make sure that everything is working:

      Your output will look similar to the following:

      Output

      dnscontrol 0.2.8-dev

      If you see a dnscontrol: command not found error, double-check your Go path setup.

      Now that you've installed DNSControl, you can create a configuration directory and connect DNSControl to your DNS provider in order to allow it to make changes to your DNS records.

      Step 2 — Configuring DNSControl

      In this step, you'll create the required configuration directories for DNSControl, and connect it to your DNS provider so that it can begin to make live changes to your DNS records.

      Firstly, create a new directory in which you can store your DNSControl configuration, and then move into it:

      • mkdir ~/dnscontrol
      • cd ~/dnscontrol

      Note: This tutorial will focus on the initial set up of DNSControl; however for production use it is recommended to store your DNSControl configuration in a version control system (VCS) such as Git. The advantages of this include full version control, integration with CI/CD for testing, seamlessly rolling-back deployments, and so on.

      If you plan to use DNSControl to write BIND zone files, you should also create the zones directory:

      BIND zone files are a raw, standardized method for storing DNS zones/records in plain text format. They were originally used for the BIND DNS server software, but are now widely adopted as the standard method for storing DNS zones. BIND zone files produced by DNSControl are useful if you want to import them to a custom or self-hosted DNS server, or for auditing purposes.

      However, if you just want to use DNSControl to push DNS changes to a managed provider, the zones directory will not be needed.

      Next, you need to configure the creds.json file, which is what will allow DNSControl to authenticate to your DNS provider and make changes. The format of creds.json differs slightly depending on the DNS provider that you are using. Please see the Service Providers list in the official DNSControl documentation to find the configuration for your own provider.

      Create the file creds.json in the ~/dnscontrol directory:

      • cd ~/dnscontrol
      • nano creds.json

      Add the sample creds.json configuration for your DNS provider to the file. If you're using DigitalOcean as your DNS provider, you can use the following:

      ~/dnscontrol/creds.json

      {
        "digitalocean": {
          "token": "your-digitalocean-oauth-token"
        }
      }
      

      This file tells DNSControl to which DNS providers you want it to connect.

      You'll need to provide some form of authentication for your DNS provider. This is usually an API key or OAuth token, but some providers require extra information, as documented in the Service Providers list in the official DNSControl documentation.

      Warning: This token will grant access to your DNS provider account, so you should protect it as you would a password. Also, ensure that if you're using a version control system, either the file containing the token is excluded (e.g. using .gitignore), or is securely encrypted in some way.

      If you're using DigitalOcean as your DNS provider, you can use the required OAuth token in your DigitalOcean account settings that you generated as part of the prerequisites.

      If you have multiple different DNS providers—for example, for multiple domain names, or delegated DNS zones—you can define these all in the same creds.json file.

      You've set up the initial DNSControl configuration directories, and configured creds.json to allow DNSControl to authenticate to your DNS provider and make changes. Next you'll create the configuration for your DNS zones.

      Step 3 — Creating a DNS Configuration File

      In this step, you'll create an initial DNS configuration file, which will contain the DNS records for your domain name or delegated DNS zone.

      dnsconfig.js is the main DNS configuration file for DNSControl. In this file, DNS zones and their corresponding records are defined using JavaScript syntax. This is known as a DSL, or Domain Specific Language. The JavaScript DSL page in the official DNSControl documentation provides further details.

      To begin, create the DNS configuration file in the ~/dnscontrol directory:

      • cd ~/dnscontrol
      • nano dnsconfig.js

      Then, add the following sample configuration to the file:

      ~/dnscontrol/dnsconfig.js

      // Providers:
      
      var REG_NONE = NewRegistrar('none', 'NONE');
      var DNS_DIGITALOCEAN = NewDnsProvider('digitalocean', 'DIGITALOCEAN');
      
      // Domains:
      
      D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
          A('@', 'your-server-ip')
      );
      

      This sample file defines a domain name or DNS zone at a particular provider, which in this case is example.com hosted by DigitalOcean. An example A record is also defined for the zone root (@), pointing to the IP of the server that you're hosting your domain/website on.

      There are three main functions that make up a basic DNSControl configuration file:

      • NewRegistrar(name, type, metadata): defines the domain registrar for your domain name. DNSControl can use this to make required changes, such as modifying the authoritative nameservers. If you only want to use DNSControl to manage your DNS zones, this can generally be left as NONE.

      • NewDnsProvider(name, type, metadata): defines a DNS service provider for your domain name or delegated zone. This is where DNSControl will push the DNS changes that you make.

      • D(name, registrar, modifiers): defines a domain name or delegated DNS zone for DNSControl to manage, as well as the DNS records present in the zone.

      You should configure NewRegistrar(), NewDnsProvider(), and D() accordingly using the Service Providers list in the official DNSControl documentation.

      If you're using DigitalOcean as your DNS provider, and only need to be able to make DNS changes (rather than authoritative nameservers as well), the sample in the preceding code block is already correct.

      Once complete, save and close the file.

      In this step, you set up a DNS configuration file for DNSControl, with the relevant providers defined. Next, you'll populate the file with some useful DNS records.

      Step 4 — Populating Your DNS Configuration File

      Next, you can populate the DNS configuration file with useful DNS records for your website or service, using the DNSControl syntax.

      Unlike traditional BIND zone files, where DNS records are written in a raw, line-by-line format, DNS records within DNSControl are defined as a function parameter (domain modifier) to the D() function, as shown briefly in Step 3.

      A domain modifier exists for each of the standard DNS record types, including A, AAAA, MX, TXT, NS, CAA, and so on. A full list of available record types is available in the Domain Modifiers section of the DNSControl documentation.

      Modifiers for individual records are also available (record modifiers). Currently these are primarily used for setting the TTL (time to live) of individual records. A full list of available record modifiers is available in the Record Modifiers section of the DNSControl documentation. Record modifiers are optional, and in most basic use cases can be left out.

      The syntax for setting DNS records varies slightly for each record type. Following are some examples for the most common record types:

      • A records:

        • Purpose: To point to an IPv4 address.
        • Syntax: A('name', 'address', optional record modifiers)
        • Example: A('@', 'your-server-ip', TTL(30))
      • AAAA records:

        • Purpose: To point to an IPv6 address.
        • Syntax: AAAA('name', 'address', optional record modifiers)
        • Example: AAAA('@', '2001:db8::1') (record modifier left out, so default TTL will be used)
      • CNAME records:

        • Purpose: To make your domain/subdomain an alias of another.
        • Syntax: CNAME('name', 'target', optional record modifiers)
        • Example: CNAME('subdomain1', 'example.org.') (note that a trailing . must be included if there are any dots in the value)
      • MX records:

        • Purpose: To direct email to specific servers/addresses.
        • Syntax: MX('name', 'priority', 'target', optional record modifiers)
        • Example: MX('@', 10, 'mail.example.net') (note that a trailing . must be included if there are any dots in the value)
      • TXT records:

        • Purpose: To add arbitrary plain text, often used for configurations without their own dedicated record type.
        • Syntax: TXT('name', 'content', optional record modifiers)
        • Example: TXT('@', 'This is a TXT record.')
      • CAA records:

        • Purpose: To restrict and report on Certificate Authorities (CAs) who can issue TLS certificates for your domain/subdomains.
        • Syntax: CAA('name', 'tag', 'value', optional record modifiers)
        • Example: CAA('@', 'issue', 'letsencrypt.org')

      In order to begin adding DNS records for your domain or delegated DNS zone, edit your DNS configuration file:

      • cd ~/dnscontrol
      • nano dnsconfig.js

      Next, you can begin populating the parameters for the existing D() function using the syntax described in the previous list, as well as the Domain Modifiers section of the official DNSControl documentation. A comma (,) must be used in-between each record.

      For reference, the code block here contains a full sample configuration for a basic, initial DNS setup:

      ~/dnscontrol/dnsconfig.js

      ...
      
      D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
          A('@', 'your-server-ip'),
          A('www', 'your-server-ip'),
          A('mail', 'your-server-ip'),
          AAAA('@', '2001:db8::1'),
          AAAA('www', '2001:db8::1'),
          AAAA('mail', '2001:db8::1'),
          MX('@', 10, 'mail.example.com.'),
          TXT('@', 'v=spf1 -all'),
          TXT('_dmarc', 'v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;')
      );
      

      Once you have completed your initial DNS configuration, save and close the file.

      In this step, you set up the initial DNS configuration file, containing your DNS records. Next, you will test the configuration and deploy it.

      Step 5 — Testing and Deploying Your DNS Configuration

      In this step, you will run a local syntax check on your DNS configuration, and then deploy the changes to the live DNS server/provider.

      Firstly, move into your dnscontrol directory:

      Next, use the preview function of DNSControl to check the syntax of your file, and output what changes it will make (without actually making them):

      If the syntax of your DNS configuration file is correct, DNSControl will output an overview of the changes that it will make. This should look similar to the following:

      Output

      ******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE A example.com your-server-ip ttl=300 #2: CREATE A www.example.com your-server-ip ttl=300 #3: CREATE A mail.example.com your-server-ip ttl=300 #4: CREATE AAAA example.com 2001:db8::1 ttl=300 #5: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 #6: CREATE AAAA www.example.com 2001:db8::1 ttl=300 #7: CREATE AAAA mail.example.com 2001:db8::1 ttl=300 #8: CREATE MX example.com 10 mail.example.com. ttl=300 ----- Registrar: none...0 corrections Done. 8 corrections.

      If you see an error warning in your output, DNSControl will provide details on what and where the error is located within your file.

      Warning: The next command will make live changes to your DNS records and possibly other settings. Please ensure that you are prepared for this, including taking a backup of your existing DNS configuration, as well as ensuring that you have the means to roll back if needed.

      Finally, you can push out the changes to your live DNS provider:

      You'll see an output similar to the following:

      Output

      ******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 SUCCESS! #2: CREATE A example.com your-server-ip ttl=300 SUCCESS! #3: CREATE AAAA example.com 2001:db8::1 ttl=300 SUCCESS! #4: CREATE AAAA www.example.com 2001:db8::1 ttl=300 SUCCESS! #5: CREATE AAAA mail.example.com 2001:db8::1 ttl=300 SUCCESS! #6: CREATE A www.example.com your-server-ip ttl=300 SUCCESS! #7: CREATE A mail.example.com your-server-ip ttl=300 SUCCESS! #8: CREATE MX example.com 10 mail.example.com. ttl=300 SUCCESS! ----- Registrar: none...0 corrections Done. 8 corrections.

      Now, if you check the DNS settings for your domain in the DigitalOcean control panel, you'll see the changes.

      A screenshot of the DigitalOcean control panel, showing some of the DNS changes that DNSControl has made.

      You can also check the record creation by running a DNS query for your domain/delegated zone. You'll see that the records have been updated accordingly:

      You'll see output showing the IP address and relevant DNS record from your zone that was deployed using DNSControl. DNS records can take some time to propagate, so you may need to wait and run this command again.

      In this final step, you ran a local syntax check of the DNS configuration file, then deployed it to your live DNS provider, and tested that the changes were made successfully.

      Conclusion

      In this article you set up DNSControl and deployed a DNS configuration to a live provider. Now you can manage and test your DNS configuration changes in a safe, offline environment before deploying them to production.

      If you wish to explore this subject further, DNSControl is designed to be integrated into your CI/CD pipeline, allowing you to run in-depth tests and have more control over your deployment to production. You could also look into integrating DNSControl into your infrastructure build/deployment processes, allowing you to deploy servers and add them to DNS completely automatically.

      If you wish to go further with DNSControl, the following DigitalOcean articles provide some interesting next steps to help integrate DNSControl into your change management and infrastructure deployment workflows:



      Source link

      How To Automatically Manage DNS Records From DigitalOcean Kubernetes Using ExternalDNS


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      When deploying web apps to Kubernetes, you usually use Services and Ingresses to expose apps beyond the cluster at your desired domain. This involves manually configuring not only the Ingress, but also the DNS records at your provider, which can be a time-consuming and error-prone process. This can become an obstacle as your application grows in complexity; when the external IP changes, it is necessary to update the DNS records accordingly.

      To overcome this, the Kubernetes sig-network team created ExternalDNS for the purpose of automatically managing external DNS records from within a Kubernetes cluster. Once deployed, ExternalDNS works in the background and requires almost no additional configuration. Whenever a Service or Ingress is created or changed, ExternalDNS will update the records right away.

      In this tutorial, you will install ExternalDNS to your DigitalOcean Kubernetes cluster via Helm and configure it to use DigitalOcean as your DNS provider. Then, you will deploy a sample web app with an Ingress and use ExternalDNS to point it to your domain name. In the end, you will have an automated DNS record managing system in place for both Services and Ingresses.

      Prerequisites

      • A DigitalOcean Kubernetes cluster with your connection configured as the kubectl default. Instructions on how to configure kubectl are shown under the Connect to your Cluster step when you create your cluster. To create a Kubernetes cluster on DigitalOcean, see Kubernetes Quickstart.

      • The Helm package manager installed on your local machine, and Tiller installed on your cluster. To do this, complete Steps 1 and 2 of the How To Install Software on Kubernetes Clusters with the Helm Package Manager tutorial.

      • The Nginx Ingress Controller installed on your cluster using Helm in order to use ExternalDNS with Ingress Resources. To do this, follow How to Set Up an Nginx Ingress on DigitalOcean Kubernetes Using Helm. You’ll need to set the publishService property to true as per the instructions in Step 2.

      • A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.

      • A fully registered domain name. This tutorial will use echo.example.com throughout. You can purchase a domain name on Namecheap, get one for free on Freenom, or use the domain registrar of your choice.

      Step 1 — Installing ExternalDNS Using Helm

      In this section, you will install ExternalDNS to your cluster using Helm and configure it to work with the DigitalOcean DNS service.

      In order to override some of the default settings of the ExternalDNS Helm chart, you’ll need to create a values.yaml file that you’ll pass in to Helm during installation. On the machine you use to access your cluster in the prerequisites, create the file by running:

      • nano externaldns-values.yaml

      Add the following lines:

      externaldns-values.yaml

      rbac:
        create: true
      
      provider: digitalocean
      
      digitalocean:
        apiToken: your_api_token
      
      interval: "1m"
      
      policy: sync # or upsert-only
      
      # domainFilters: [ 'example.com' ]
      

      In the first block, you enable RBAC (Role Based Access Control) manifest creation, which must be enabled on RBAC-enabled Kubernetes clusters like DigitalOcean. In the next line, you set the DNS service provider to DigitalOcean. Then, in the next block, you’ll add your DigitalOcean API token by replacing your_api_token.

      The next line sets the interval at which ExternalDNS will poll for changes to Ingresses and Services. You can set it to a lower value to propogate changes to your DNS faster.

      The policy setting determines whether ExternalDNS will only insert DNS records (upsert-only) or create and delete them as needed (sync). Fortunately, since version 0.3, ExternalDNS supports the concept of ownership by creating accompanying TXT records in which it stores information about the domains it creates, limiting its scope of action to only those it created.

      The domainFilters parameter is used for limiting the domains that ExternalDNS can manage. You can uncomment it and enter your domains in the form of a string array, but this isn’t necessary.

      When you’ve finished editing, save and close the file.

      Now, install ExternalDNS to your cluster by running the following command:

      • helm install stable/external-dns --name external-dns -f externaldns-values.yaml

      The output will look similar to the following:

      Output

      NAME: external-dns LAST DEPLOYED: ... NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE external-dns-69c545655f-xqjjf 0/1 ContainerCreating 0 0s ==> v1/Secret NAME TYPE DATA AGE external-dns Opaque 1 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-dns ClusterIP 10.245.47.69 <none> 7979/TCP 0s ==> v1/ServiceAccount NAME SECRETS AGE external-dns 1 0s ==> v1beta1/ClusterRole NAME AGE external-dns 0s ==> v1beta1/ClusterRoleBinding NAME AGE external-dns 0s ==> v1beta1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE external-dns 0/1 1 0 0s NOTES: ...

      You can verify the ExternalDNS creation by running the following command:

      • kubectl --namespace=default get pods -l "app=external-dns,release=external-dns" -w

      Output

      NAME READY STATUS RESTARTS AGE external-dns-69bfcf8ccb-7j4hp 0/1 ContainerCreating 0 3s

      You’ve installed ExternalDNS to your Kubernetes cluster. Next, you will deploy an example web app, expose it using an Nginx Ingress, and let ExternalDNS automatically point your domain name to the appropriate Load Balancer.

      Step 2 — Deploying and Exposing an Example Web App

      In this section, you will deploy a dummy web app to your cluster in order to expose it using your Ingress. Then you’ll set up ExternalDNS to automatically configure DNS records for you. In the end, you will have DNS records for your domain pointed to the Load Balancer of the Ingress.

      The dummy web app you’ll deploy is http-echo by Hashicorp. It is an in-memory web server that echoes back the message you give it. You’ll store its Kubernetes manifests in a file named echo.yaml. Create it and open it for editing:

      Add the following lines to your file:

      echo.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
      spec:
        rules:
        - host: echo.example.com
          http:
            paths:
            - backend:
                serviceName: echo
                servicePort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: echo
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo
      spec:
        selector:
          matchLabels:
            app: echo
        replicas: 3
        template:
          metadata:
            labels:
              app: echo
          spec:
            containers:
            - name: echo
              image: hashicorp/http-echo
              args:
              - "-text=Echo!"
              ports:
              - containerPort: 5678
      

      In this configuration, you define a Deployment, an Ingress, and a Service. The Deployment consists of three replicas of the http-echo app, with a custom message (Echo!) passed in. The Service is defined to allow access to the Pods in the Deployment via port 80. The Ingress is configured to expose the Service at your domain.

      Replace echo.example.com with your domain, then save and close the file.

      Now there is no need for you to configure the DNS records for the domain manually. ExternalDNS will do so automatically, as soon as you apply the configuration to Kubernetes.

      To apply the configuration, run the following command:

      • kubectl create -f echo.yaml

      You'll see the following output:

      Output

      ingress.extensions/echo-ingress created service/echo created deployment.apps/echo created

      You'll need to wait a short amount of time for ExternalDNS to notice the changes and create the appropriate DNS records. The interval setting in the Helm chart governs the length of time you'll need to wait for your DNS record creation. In values.yaml, the interval length is set to 1 minute by default.

      You can visit your DigitalOcean Control Panel to see an A and TXT record.

      Control Panel - Generated DNS Records

      Once the specified time interval has passed, access your domain using curl:

      You'll see the following output:

      Output

      Echo!

      This message confirms you've configured ExternalDNS and created the necessary DNS records to point to the Load Balancer of the Nginx Ingress Controller. If you see an error message, give it some time. Or, you can try accessing your domain from your browser where you'll see Echo!.

      You've tested ExternalDNS by deploying an example app with an Ingress. You can also observe the new DNS records in your DigitalOcean Control Panel. In the next step, you'll expose the Service at your domain name.

      Step 3 — (Optional) Exposing the App Using a Service

      In this optional section, you'll use Services with ExternalDNS instead of Ingresses. ExternalDNS allows you to make different Kubernetes resources available to DNS servers. Using Services is a similar process to Ingresses with the configuration modified for this alternate resource.

      Note: Following this step will delete the DNS records you've just created.

      Since you'll be customizing the Service contained in echo.yaml, you won't need the echo-ingress anymore. Delete it using the following command:

      • kubectl delete ing echo-ingress

      The output will be:

      Output

      ingress.extensions/echo-ingress deleted

      ExternalDNS will delete the existing DNS records it created in the previous step. In the remainder of the step, you can use the same domain you have used before.

      Next, open the echo.yaml file for editing:

      Replace the file contents with the following lines:

      echo.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo
        annotations:
          external-dns.alpha.kubernetes.io/hostname: echo.example.com
      spec:
        type: LoadBalancer
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo
      spec:
        selector:
          matchLabels:
            app: echo
        replicas: 3
        template:
          metadata:
            labels:
              app: echo
          spec:
            containers:
            - name: echo
              image: hashicorp/http-echo
              args:
              - "-text=Echo!"
              ports:
              - containerPort: 5678
      

      You've removed Ingress from the file for the previous set up and changed the Service type to LoadBalancer. Furthermore, you've added an annotation specifying the domain name for ExternalDNS.

      Apply the changes to your cluster by running the following command:

      • kubectl apply -f echo.yaml

      The output will be:

      Output

      service/echo configured deployment.apps/echo configured

      You can watch the Service's Load Balancer become available by running:

      You will see output similar to the following:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo LoadBalancer 10.245.81.235 <pending> 80:31814/TCP 8s ...

      As in the previous step, you'll need to wait some time for the DNS records to be created and propagated. Once that is done, curl the domain you specified:

      The output will be the same as the previous step:

      Output

      Echo!

      If you get an error, wait a little longer, or you can try a different domain. Since DNS records are cached on client systems, it may take a long time for the changes to actually propagate.

      In this step, you created a Service (of type LoadBalancer) and pointed it to your domain name using ExternalDNS.

      Conclusion

      ExternalDNS works silently in the background and provides a friction-free experience. Your Kubernetes cluster has just become the central source of truth regarding the domains. You won't have to manually update DNS records anymore.

      The real power of ExternalDNS will become apparent when creating testing environments from a Continuous Delivery system. If you want to set up one such system on your Kubernetes cluster, visit How To Set Up a CD Pipeline with Spinnaker on DigitalOcean Kubernetes.



      Source link