One place for hosting & domains

      December 2018

      Configure SPF and DKIM With Postfix on Debian 9


      Updated by Linode

      Contributed by

      Linode

      This guide will instruct you on how to set up SPF and DKIM with Postfix.

      SPF (Sender Policy Framework) is a system that identifies to mail servers what hosts are allowed to send email for a given domain. Setting up SPF helps to prevent your email from being classified as spam.

      DKIM (DomainKeys Identified Mail) is a system that lets your official mail servers add a signature to headers of outgoing email and identifies your domain’s public key so other mail servers can verify the signature. As with SPF, DKIM helps keep your mail from being considered spam. It also lets mail servers detect when your mail has been tampered with in transit.

      DMARC (Domain Message Authentication, Reporting & Conformance) allows you to advertise to mail servers what your domain’s policies are regarding mail that fails SPF and/or DKIM validations. It additionally allows you to request reports on failed messages from receiving mail servers.

      The DNS instructions for setting up SPF, DKIM and DMARC are generic. The instructions for configuring the SPF policy agent and OpenDKIM into Postfix should work on any distribution after making respective code adjustments for the package tool, and identifying the exact path to the Unix socket file.

      Note

      The steps required in this guide require root privileges. Be sure to run the steps below as root or with the sudo prefix. For more information on privileges see our Users and Groups guide.

      Caution

      You must already have Postfix installed, configured and working. Refer to the Linode Postfix Guides for assistance.

      Publishing an SPF DNS record without having the SPF policy agent configured within Postfix is safe; however, publishing DKIM DNS records without having OpenDKIM working correctly within Postfix can result in your email being discarded by the recipient’s email server.

      Install DKIM, SPF and Postfix

      1. Install the four required packages:

        apt-get install opendkim opendkim-tools postfix-policyd-spf-python postfix-pcre
        
      2. Add user postfix to the opendkim group so that Postfix can access OpenDKIM’s socket when it needs to:

        adduser postfix opendkim
        

      Set up SPF

      Add SPF records to DNS

      The value in an SPF DNS record will look something like the following examples. The full syntax is at the SPF record syntax page.

      Example 1 Allow mail from all hosts listed in the MX records for the domain:

      v=spf1 mx -all
      

      Example 2 Allow mail from a specific host:

      v=spf1 a:mail.example.com -all
      
      • The v=spf1 tag is required and has to be the first tag.

      • The last tag, -all, indicates that mail from your domain should only come from servers identified in the SPF string. Anything coming from any other source is forging your domain. An alternative is ~all, indicating the same thing but also indicating that mail servers should accept the message and flag it as forged instead of rejecting it outright. -all makes it harder for spammers to forge your domain successfully; it is the recommended setting. ~all reduces the chances of email getting lost because an incorrect mail server was used to send mail. ~all can be used if you don’t want to take chances.

      The tags between identify eligible servers from which email to your domain can originate.

      • mx is a shorthand for all the hosts listed in MX records for your domain. If you’ve got a solitary mail server, mx is probably the best option. If you’ve got a backup mail server (a second MX record), using mx won’t cause any problems. Your backup mail server will be identified as an authorized source for email although it will probably never send any.

      • The a tag lets you identify a specific host by name or IP address, letting you specify which hosts are authorized. You’d use a if you wanted to prevent the backup mail server from sending outgoing mail or if you wanted to identify hosts other than your own mail server that could send mail from your domain (e.g., putting your ISP’s outgoing mail servers in the list so they’d be recognized when you had to send mail through them).

      For now, we’re going to stick with the mx version. It’s simpler and correct for most basic configurations, including those that handle multiple domains. To add the record, go to your DNS management interface and add a record of type TXT for your domain itself (i.e., a blank hostname) containing this string:

      v=spf1 mx -all
      

      If you’re using Linode’s DNS Manager, go to the domain zone page for the selected domain and add a new TXT record. The screen will look something like this once you’ve got it filled out:

      Linode DNS manager add SPF TXT record

      If your DNS provider allows it (DNS Manager doesn’t), you should also add a record of type SPF, filling it in the same way as you did the TXT record.

      Note

      The values for the DNS records above – and for the rest of this guide – are done in the style that Linode’s DNS Manager needs them to be in. If you’re using another provider, that respective system may require the values in a different style. For example freedns.afraid.org requires the values to be written in the style found in BIND zonefiles. Thus, the above SPF record’s value would need to be wrapped in double-quotes like this: "v=spf1 mx -all". You’ll need to consult your DNS provider’s documentation for the exact style required.

      Add the SPF policy agent to Postfix

      The Python SPF policy agent adds SPF policy-checking to Postfix. The SPF record for the sender’s domain for incoming mail will be checked and, if it exists, mail will be handled accordingly. Perl has its own version, but it lacks the full capabilities of Python policy agent.

      1. If you are using SpamAssassin to filter spam, you may want to edit /etc/postfix-policyd-spf-python/policyd-spf.conf to change the HELO_reject and Mail_From_reject settings to False. This edit will cause the SPF policy agent to run its tests and add a message header with the results in it while not rejecting any messages. You may also want to make this change if you want to see the results of the checks but not actually apply them to mail processing. Otherwise, just go with the standard settings.

      2. Edit /etc/postfix/master.cf and add the following entry at the end:

        /etc/postfix/master.cf
        1
        2
        
        policyd-spf  unix  -       n       n       -       0       spawn
            user=policyd-spf argv=/usr/bin/policyd-spf
      3. Open /etc/postfix/main.cf and add this entry to increase the Postfix policy agent timeout, which will prevent Postfix from aborting the agent if transactions run a bit slowly:

        /etc/postfix/main.cf
        1
        
        policyd-spf_time_limit = 3600
      4. Edit the smtpd_recipient_restrictions entry to add a check_policy_service entry:

        /etc/postfix/main.cf
        1
        2
        3
        4
        5
        
        smtpd_recipient_restrictions =
            ...
            reject_unauth_destination,
            check_policy_service unix:private/policyd-spf,
            ...

        Make sure to add the check_policy_service entry after the reject_unauth_destination entry to avoid having your system become an open relay. If reject_unauth_destination is the last item in your restrictions list, add the comma after it and omit the comma at the end of the check_policy_service item above.

      5. Restart Postfix:

        systemctl restart postfix
        

      You can check the operation of the policy agent by looking at raw headers on incoming email messages for the SPF results header. The header the policy agent adds to messages should look something like this:

      Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=127.0.0.1; helo=mail.example.com; envelope-from=text@example.com; receiver=tknarr@silverglass.org
      

      This header indicates a successful check against the SPF policy of the sending domain. If you changed the policy agent settings in Step 1 to not reject mail that fails the SPF check, you may see Fail results in this header. You won’t see this header on outgoing or local mail.

      The SPF policy agent also logs to /var/log/mail.log. In the mail.log file you’ll see messages like this from the policy agent:

      Jan  7 06:24:44 arachnae policyd-spf[21065]: None; identity=helo; client-ip=127.0.0.1; helo=mail.example.com; envelope-from=test@example.com; receiver=tknarr@silverglass.org
      Jan  7 06:24:44 arachnae policyd-spf[21065]: Pass; identity=mailfrom; client-ip=127.0.0.1; helo=mail.example.com; envelope-from=test@example.com; receiver=tknarr@silverglass.org
      

      The first message is a check of the HELO command, in this case indicating that there wasn’t any SPF information matching the HELO (which is perfectly OK). The second message is the check against the envelope From address, and indicates the address passed the check and is coming from one of the outgoing mail servers the sender’s domain has said should be sending mail for that domain. There may be other statuses in the first field after the colon indicating failure, temporary or permanent errors and so on.

      Set up DKIM

      DKIM involves setting up the OpenDKIM package, hooking it into Postfix, and adding DNS records.

      Configure OpenDKIM

      1. The main OpenDKIM configuration file /etc/opendkim.conf needs to look like this:

        /etc/opendkim.conf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        
        # This is a basic configuration that can easily be adapted to suit a standard
        # installation. For more advanced options, see opendkim.conf(5) and/or
        # /usr/share/doc/opendkim/examples/opendkim.conf.sample.
        
        # Log to syslog
        Syslog          yes
        # Required to use local socket with MTAs that access the socket as a non-
        # privileged user (e.g. Postfix)
        UMask           002
        # OpenDKIM user
        # Remember to add user postfix to group opendkim
        UserID          opendkim
        
        # Map domains in From addresses to keys used to sign messages
        KeyTable        /etc/opendkim/key.table
        SigningTable        refile:/etc/opendkim/signing.table
        
        # Hosts to ignore when verifying signatures
        ExternalIgnoreList  /etc/opendkim/trusted.hosts
        InternalHosts       /etc/opendkim/trusted.hosts
        
        # Commonly-used options; the commented-out versions show the defaults.
        Canonicalization    relaxed/simple
        Mode            sv
        SubDomains      no
        #ADSPAction     continue
        AutoRestart     yes
        AutoRestartRate     10/1M
        Background      yes
        DNSTimeout      5
        SignatureAlgorithm  rsa-sha256
        
        # Always oversign From (sign using actual From and a null From to prevent
        # malicious signatures header fields (From and/or others) between the signer
        # and the verifier.  From is oversigned by default in the Debian package
        # because it is often the identity key used by reputation systems and thus
        # somewhat security sensitive.
        OversignHeaders     From
        
        # Define the location of the Socket and PID files
        Socket              local:/var/spool/postfix/opendkim/opendkim.sock
        PidFile             /var/run/opendkim/opendkim.pid

        Edit /etc/opendkim.conf and replace it’s contents with the above.

      2. Ensure that file permissions are set correctly:

        chmod u=rw,go=r /etc/opendkim.conf
        
      3. Create the directories to hold OpenDKIM’s data files, assign ownership to the opendkim user, and restrict the file permissions:

        mkdir /etc/opendkim
        mkdir /etc/opendkim/keys
        chown -R opendkim:opendkim /etc/opendkim
        chmod go-rw /etc/opendkim/keys
        
      4. Create the signing table /etc/opendkim/signing.table. It needs to have one line per domain that you handle email for. Each line should look like this:

        /etc/opendkim/signing.table

        Replace example.com with your domain and example with a short name for the domain. The first field is a pattern that matches e-mail addresses. The second field is a name for the key table entry that should be used to sign mail from that address. For simplicity’s sake, we’re going to set up one key for all addresses in a domain.

      5. Create the key table /etc/opendkim/key.table. It needs to have one line per short domain name in the signing table. Each line should look like this:

        /etc/opendkim/key.table
        1
        
        example     example.com:YYYYMM:/etc/opendkim/keys/example.private

        Replace example with the example value you used for the domain in the signing table (make sure to catch the second occurrence at the end, where it’s followed by .private). Replace example.com with your domain name and replace the YYYYMM with the current 4-digit year and 2-digit month (this is referred to as the selector). The first field connects the signing and key tables.

        The second field is broken down into 3 sections separated by colons.

        • The first section is the domain name for which the key is used.
        • The second section is a selector used when looking up key records in DNS.
        • The third section names the file containing the signing key for the domain.

        Note

        The flow for DKIM lookup starts with the sender’s address. The signing table is scanned until an entry whose pattern (first item) matches the address is found. Then, the second item’s value is used to locate the entry in the key table whose key information will be used. For incoming mail the domain and selector are then used to find the public key TXT record in DNS and that public key is used to validate the signature. For outgoing mail the private key is read from the named file and used to generate the signature on the message.

      6. Create the trusted hosts file /etc/opendkim/trusted.hosts. Its contents need to be:

        /etc/opendkim/trusted.hosts
        1
        2
        3
        4
        5
        6
        
        127.0.0.1
        ::1
        localhost
        myhostname
        myhostname.example.com
        example.com

        When creating the file, change myhostname to the name of your server and replace example.com with your own domain name. We’re identifying the hosts that users will be submitting mail through and should have outgoing mail signed, which for basic configurations will be your own mail server.

      7. Make sure the ownership and permissions on /etc/opendkim and it’s contents are correct (opendkim should own everything, the keys directory should only be accessible by the owner) by running the following commands:

        chown -R opendkim:opendkim /etc/opendkim
        chmod -R go-rwx /etc/opendkim/keys
        
      8. Generate keys for each domain:

        opendkim-genkey -b 2048 -h rsa-sha256 -r -s YYYYMM -d example.com -v
        

        Replace YYYYMM with the current year and month as in the key table. This will give you two files, YYYYMM.private containing the key and YYYYMM.txt containing the TXT record you’ll need to set up DNS. Rename the files so they have names matching the third section of the second field of the key table for the domain:

        mv YYYYMM.private example.private
        mv YYYYMM.txt example.txt
        

        Repeat the commands in this step for every entry in the key table. The -b 2048 indicates the number of bits in the RSA key pair used for signing and verification. 1024 bits is the minimum, but with modern hardware 2048 bits is safer. (It’s possible 4096 bits will be required at some point.)

      9. Make sure the ownership, permissions and contents on /etc/opendkim are correct by running the following commands:

        cd /etc
        chown -R opendkim:opendkim /etc/opendkim
        chmod -R go-rw /etc/opendkim/keys
        
      10. Check that OpenDKIM starts correctly:

        systemctl restart opendkim
        

        You should not get error messages, but if you do, use:

        systemctl status -l opendkim
        

        to get the status and untruncated error messages.

      Set up DNS

      As with SPF, DKIM uses TXT records to hold information about the signing key for each domain. Using YYYYMM as above, you need to make a TXT record for the host YYYYMM._domainkey for each domain you handle mail for. Its value can be found in the example.txt file for the domain. Those files look like this:

      example.txt
      1
      2
      3
      
      201510._domainkey  IN  TXT ( "**v=DKIM1; h=rsa-sha256; k=rsa; s=email; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXR"
          "ZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwzPaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB**" )  ; ----- DKIM key 201510 for example.com

      The value inside the parentheses is what you want. Select and copy the entire region from (but not including) the double-quote before v=DKIM1 on up to (but not including) the final double-quote before the closing parentheses. Then edit out the double-quotes within the copied text and the whitespace between them. Also change h=rsa-sha256 to h=sha256. From the above file the result would be:

      example-copied.txt
      1
      
      v=DKIM1; h=sha256; k=rsa; s=email; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXRZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwzPaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB

      Paste that into the value for the TXT record.

      If you’re using Linode’s DNS manager, this is what the add TXT record screen will look like when you have it filled out:

      Linode DNS manager add SPF TXT record

      Repeat this for every domain you handle mail for, using the .txt file for that domain.

      Test your configuration

      Test the keys for correct signing and verification using the opendkim-testkey command:

      opendkim-testkey -d example.com -s YYYYMM
      

      If everything is OK you shouldn’t get any output. If you want to see more information, add -vvv to the end of the command. That produces verbose debugging output. The last message should be “key OK”. Just before that you may see a “key not secure” message. That’s normal and doesn’t signal an error, it just means your domain isn’t set up for DNSSEC yet.

      Hook OpenDKIM into Postfix

      1. Create the OpenDKIM socket directory in Postfix’s work area and make sure it has the correct ownership:

        mkdir /var/spool/postfix/opendkim
        chown opendkim:postfix /var/spool/postfix/opendkim
        
      2. Set the correct socket for Postfix in the OpenDKIM defaults file /etc/default/opendkim:

        /etc/default/opendkim
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        # Command-line options specified here will override the contents of
        # /etc/opendkim.conf. See opendkim(8) for a complete list of options.
        #DAEMON_OPTS=""
        #
        # Uncomment to specify an alternate socket
        # Note that setting this will override any Socket value in opendkim.conf
        SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"
        #SOCKET="inet:54321" # listen on all interfaces on port 54321
        #SOCKET="inet:12345@localhost" # listen on loopback on port 12345
        #SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345

        Uncomment the first SOCKET line and edit it so it matches the uncommented line in the above file. The path to the socket is different from the default because on Debian 9 the Postfix process that handles mail runs in a chroot jail and can’t access the normal location.

      3. Edit /etc/postfix/main.cf and add a section to activate processing of e-mail through the OpenDKIM daemon:

        /etc/postfix/main.cf
        1
        2
        3
        4
        5
        6
        7
        
        # Milter configuration
        # OpenDKIM
        milter_default_action = accept
        # Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2
        milter_protocol = 6
        smtpd_milters = local:opendkim/opendkim.sock
        non_smtpd_milters = local:opendkim/opendkim.sock

        You can put this anywhere in the file. The usual practice is to put it after the smtpd_recipient_restrictions entry. You’ll notice the path to the socket isn’t the same here as it was in the /etc/defaults/opendkim file. That’s because of Postfix’s chroot jail, the path here is the path within that restricted view of the filesystem instead of within the actual filesystem.

      4. Restart the OpenDKIM daemon so it sets up the correct socket for Postfix:

        systemctl restart opendkim
        
      5. Restart Postfix so it starts using OpenDKIM when processing mail:

        systemctl restart postfix
        

      Verify that everything’s fully operational

      The easiest way to verify that everything’s working is to send a test e-mail to check-auth@verifier.port25.com using an email client configured to submit mail to the submission port on your mail server. It will analyze your message and mail you a report indicating whether your email was signed correctly or not. It also reports on a number of other things such as SPF configuration and SpamAssassin flagging of your domain. If there’s a problem, it’ll report what the problem was.

      Optional: Set up Author Domain Signing Practices (ADSP)

      As a final item, you can add an ADSP policy to your domain saying that all emails from your domain should be DKIM-signed. As usual, it’s done with a TXT record for host _adsp._domainkey in your domain with a value of dkim=all. If you’re using Linode’s DNS Manager, the screen for the new text record will look like this:

      Linode DNS Manager add ADSP TXT record

      You don’t need to set this up, but doing so makes it harder for anyone to forge email from your domains because recipient mail servers will see the lack of a DKIM signature and reject the message.

      Optional: Set up Domain Message Authentication, Reporting & Conformance (DMARC)

      The DMARC DNS record can be added to advise mail servers what you think they should do with emails claiming to be from your domain that fail validation with SPF and/or DKIM. DMARC also allows you to request reports about mail that fails to pass one or more validation check. DMARC should only be set up if you have SPF and DKIM set up and operating successfully. If you add the DMARC DNS record without having both SPF and DKIM in place, messages from your domain will fail validation which may cause them to be discarded or relegated to a spam folder.

      The DMARC record is a TXT record for host _dmarc in your domain containing the following recommended values:

      v=DMARC1;p=quarantine;sp=quarantine;adkim=r;aspf=r
      

      This requests mail servers to quarantine (do not discard, but separate from regular messages) any email that fails either SPF or DKIM checks. No reporting is requested. Very few mail servers implement the software to generate reports on failed messages, so it is often unnecessary to request them. If you do wish to request reports, the value would be similar to this example, added as a single string:

      v=DMARC1;p=quarantine;sp=quarantine;adkim=r;aspf=r;fo=1;rf=afrf;rua=mailto:user@example.com
      

      Replace user@example.com in the mailto: URL with your own email or an email address you own dedicated to receiving reports (an address such as dmarc@example.com). This requests aggregated reports in XML showing how many messages fell into each combination of pass and fail results and the mail server addresses sending them. If you’re using Linode’s DNS Manager, the screen for the new text record will look like this:

      Linode DNS Manager add DMARC TXT record

      DMARC records have a number of available tags and options. These tags are used to control your authentication settings:

      • v specifies the protocol version, in this case DMARC1.
      • p determines the policy for the root domain, such as “example.com.” The available options:
        • quarantine instructs that if an email fails validation, the recipient should set it aside for processing.
        • reject requests that the receiving mail server reject the emails that fail validation.
        • none requests that the receiver take no action if an email does not pass validation.
      • sp determines the policy for subdomains, such as “subdomain.example.com.” It takes the same arguments as the p tag.
      • adkim specifies the alignment mode for DKIM, which determines how strictly DKIM records are validated. The available options are:
        • r relaxed alignment mode, DKIM authentication is less strictly enforced.
        • s strict alignment mode. Only an exact match with the DKIM entry for the root domain will be seen as validated.
      • aspf determines the alignment mode for SPF verification. It takes the same arguments as adkim.

      If you wish to receive authentication failure reports, DMARC provides a number of configuration options. You can use the following tags to customize the formatting of your reports, as well as the criteria for report creation.

      • rua specifies the email address that will receive aggregate reports. This uses the mailto:user@example.com syntax, and accepts multiple addresses separated by commas. Aggregate reports are usually generated once per day.
      • ruf specifies the email address that will receive detailed authentication failure reports. This takes the same arguments as rua. With this option, each authentication failure would result in a separate report.
      • fo allows you to specify which failed authentication methods will be reported. One or more of the following options can be used:
        • 0 will request a report if all authentication methods fail. For example, if an SPF check were to fail but DKIM authentication was successful, a report would not be sent.
        • 1 requests a report if any authentication check fails.
        • d requests a report if a DKIM check fails.
        • s requests a report if an SPF check fails.
      • rf determines the format used for authentication failure reports. Available options:
        • afrf uses the Abuse Report format as defined by RFC 5965.
        • iodef uses the Incident Object Description Exchange format as defined by RFC 5070.

      Key rotation

      The reason the YYYYMM format is used for the selector is that best practice calls for changing the DKIM signing keys every so often (monthly is recommended, and no longer than every 6 months). To do that without disrupting messages in transit, you generate the new keys using a new selector. The process is:

      1. Generate new keys as in step 8 of Configure OpenDKIM. Do this in a scratch directory, not directly in /etc/opendkim/keys. Use the current year and month for the YYYYMM selector value, so it’s different from the selector currently in use.

      2. Use the newly-generated .txt files to add the new keys to DNS as in the DKIM Set Up DNS section, using the new YYYYMM selector in the host names. Don’t remove or alter the existing DKIM TXT records. Once this is done, verify the new key data using the following command (replacing example.com, example and YYYYMM with the appropriate values):

        opendkim-testkey -d example.com -s YYYYMM -k example.private
        

        Add the -vvv switch to get debugging output if you need it to diagnose any problems. Correct any problems before proceeding, beginning to use the new private key file and selector when opendkim-testkey doesn’t indicate a successful verification will cause problems with your email including non-receipt of messages.

      3. Stop Postfix and OpenDKIM with systemctl stop postfix opendkim so that they won’t be processing mail while you’re changing out keys.

      4. Copy the newly-generated .private files into place and make sure their ownership and permissions are correct by running these commands from the directory in which you generated the key files:

        cp *.private /etc/opendkim/keys/
        chown opendkim:opendkim /etc/opendkim/keys/*
        chmod go-rw /etc/opendkim/keys/*
        

        Use the opendkim-testkey command as described above to ensure that your new record is propagated before you continue.

      5. Edit /etc/opendkim/key.table and change the old YYYYMM values to the new selector, reflecting the current year and month. Save the file.

      6. Restart OpenDKIM and Postfix by:

        systemctl start opendkim
        systemctl start postfix
        

        Make sure they both start without any errors.

      7. After a couple of weeks, all email in transit should either have been delivered or bounced and the old DKIM key information in DNS won’t be needed anymore. Delete the old YYYYMM._domainkey TXT records in each of your domains, leaving just the newest ones (most recent year and month). Don’t worry if you forget and leave the old keys around longer than planned. There’s no security issue. Removing the obsolete records is more a matter of keeping things neat and tidy than anything else.

      More Information

      You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

      Find answers, ask questions, and help others.

      This guide is published under a CC BY-ND 4.0 license.



      Source link

      Install Caddy on Arch Linux


      Updated by Linode

      Contributed by

      Claudio Costa

      Before You Begin

      1. Familiarize yourself with our Getting Started guide and complete the steps for setting your Linode’s hostname and timezone.

      2. This guide will use sudo wherever possible. Complete the sections of our Securing Your Server guide to create a standard user account, harden SSH access and remove unnecessary network services.

      3. You will need to register your site’s domain name and follow our DNS Manager Overview guide to point your domain to your Linode.

      4. Update your system with sudo pacman -Syu

      5. Install the development package group with sudo pacman -S base-devel

      What is Caddy?

      Caddy is an open source HTTP/2 capable web server with automatic HTTPS written in Go. It supports a variety of web site technologies, includes security defaults, and is very easy to use.

      Install Caddy

      You can install Caddy on Arch Linux by using a snapshot from the Arch User Repository (AUR).

      1. Download the snapshot from the AUR:

        curl https://aur.archlinux.org/cgit/aur.git/snapshot/caddy.tar.gz -o caddy.tar.gz
        
      2. Unpack the snapshot:

        tar xf caddy.tar.gz
        
      3. Navigate to the caddy directory:

        cd caddy
        
      4. Build and install the package:

        makepkg -si
        

      Test Caddy

      1. Start the Caddy web server:

        sudo systemctl start caddy
        
      2. Enable the Caddy service:

        sudo systemctl enable caddy
        
      3. Navigate to your Linode’s domain name or IP address in a web browser. You should see the Caddy default page displayed.

      Configure Caddy

      Caddy configuration files reside in /etc/caddy/ and website configuration files should be created in the /etc/caddy/caddy.conf.d/ directory.

      1. Create a sample configuration file for your website. Replace example.com with your Linode’s domain name. If you have not set up a domain, but still want to get started with Caddy, replace example.com with :80.

        /etc/caddy/caddy.conf.d/example.com.conf
        1
        2
        3
        
        example.com {
            root /usr/share/caddy/
        }

        Note

        If you choose to serve your site from a directory other than /usr/share/caddy/, you must remove the Caddy test site files located in that directory. The /usr/share/caddy/ directory is prioritized over other locations, so any files stored in that directory will be served first, even if you have configured a different directory location.

      2. Reload Caddy:

        sudo systemctl reload caddy
        
      3. Navigate to your Linode’s domain name in a web browser. You should be able to see content served from the root directory configured above.

      More Information

      You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

      Find answers, ask questions, and help others.

      This guide is published under a CC BY-ND 4.0 license.



      Source link

      Import Existing Infrastructure to Terraform


      Updated by Linode Contributed by Linode

      Terraform is an orchestration tool that uses declarative code to build, change, and version infrastructure that is made up of server instances and services. You can use Linode’s official Terraform provider to interact with Linode services. Existing Linode infrastructure can be imported and brought under Terraform management. This guide will describe how to import existing Linode infrastructure into Terraform using the official Linode provider plugin.

      Before You Begin

      1. Terraform and the Linode Terraform provider should be installed in your development environment. You should also have a basic understanding of Terraform resources. To install and learn about Terraform, read our Use Terraform to Provision Linode Environments guide.

      2. To use Terraform you must have a valid API access token. For more information on creating a Linode API access token, visit our Getting Started with the Linode API guide.

      3. This guide uses the Linode CLI to retrieve information about the Linode infrastructure you will import to Terraform. For more information on the setup, installation, and usage of the Linode CLI, check out the Using the Linode CLI guide.

      Terraform’s Import Command

      Throughout this guide the terraform import command will be used to import Linode resources. At the time of writing this guide, the import command does not generate a Terraform resource configuration. Instead, it imports your existing resources into Terraform’s state.

      State is Terraform’s stored JSON mapping of your current Linode resources to their configurations. You can access and use the information provided by the state to manually create a corresponding resource configuration file and manage your existing Linode infrastructure with Terraform.

      Additionally, there is no current way to import more than one resource at a time. All resources must be individually imported.

      Caution

      When importing your infrastructure to Terraform, failure to accurately provide your Linode service’s ID information can result in the unwanted alteration or destruction of the service. Please follow the instructions provided in this guide carefully. It might be beneficial to use multiple Terraform Workspaces to manage separate testing and production infrastructures.

      Import a Linode to Terraform

      Retrieve Your Linode’s ID

      1. Using the Linode CLI, retrieve a list of all your Linode instances and find the ID of the Linode you would like to manage under Terraform:

        linode-cli linodes list --json --pretty
        
          
        [
          {
            "id": 11426126,
            "image": "linode/debian9",
            "ipv4": [
            "192.0.2.2"
            ],
            "label": "terraform-import",
            "region": "us-east",
            "status": "running",
            "type": "g6-standard-1"
          }
        ]
        
        

        This command will return a list of your existing Linodes in JSON format. From the list, find the Linode you would like to import and copy down its corresponding id. In this example, the Linode’s ID is 11426126. You will use your Linode’s ID to import your Linode to Terraform.

      Create An Empty Resource Configuration

      1. Ensure you are in your Terraform project directory. Create a Terraform configuration file to manage the Linode instance you will import in the next section. Your file can be named anything you like, but it must end in .tf. Add a Linode provider block with your API access token and an empty linode_instance resource configuration block in the file:

        Note

        The example resource block defines example_label as the label. This can be changed to any value you prefer. This label is used to reference your Linode resource configuration within Terraform, and does not have to be the same label originally assigned to the Linode when it was created outside of Terraform.

        linode_import.tf
        1
        2
        3
        4
        5
        
        provider "linode" {
            token = "your_API_access_token"
        }
        
        resource "linode_instance" "example_label" {}

      Import Your Linode to Terraform

      1. Run the import command, supplying the linode_instance resource’s label, and the Linode’s ID that was retrieved in the Retrieve Your Linode’s ID section :

        terraform import linode_instance.example_label linodeID
        

        You should see a similar output:

          
        linode_instance.example_label: Importing from ID "11426126"...
        linode_instance.example_label: Import complete!
          Imported linode_instance (ID: 11426126)
        linode_instance.example_label: Refreshing state... (ID: 11426126)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        

        This command will create a terraform.tfstate file with information about your Linode. You will use this information to fill out your resource configuration.

      2. To view the information created by terraform import, run the show command. This command will display a list of key-value pairs representing information about the imported Linode instance.

        terraform show
        

        You should see an output similar to the following:

          
        linode_instance.example_label:
          id = 11426126
          alerts.# = 1
          alerts.0.cpu = 90
          alerts.0.io = 10000
          alerts.0.network_in = 10
          alerts.0.network_out = 10
          alerts.0.transfer_quota = 80
          backups.# = 1
          boot_config_label = My Debian 9 Disk Profile
          config.# = 1
          config.0.comments =
          config.0.devices.# = 1
          config.0.devices.0.sda.# = 1
          config.0.devices.0.sda.0.disk_id = 24170011
          config.0.devices.0.sda.0.disk_label = Debian 9 Disk
          config.0.devices.0.sda.0.volume_id = 0
          config.0.devices.0.sdb.# = 1
          config.0.devices.0.sdb.0.disk_id = 24170012
          config.0.devices.0.sdb.0.disk_label = 512 MB Swap Image
          config.0.devices.0.sdb.0.volume_id = 0
          config.0.devices.0.sdc.# = 0
          config.0.devices.0.sdd.# = 0
          config.0.devices.0.sde.# = 0
          config.0.devices.0.sdf.# = 0
          config.0.devices.0.sdg.# = 0
          config.0.devices.0.sdh.# = 0
          config.0.helpers.# = 1
          config.0.helpers.0.devtmpfs_automount = true
          config.0.helpers.0.distro = true
          config.0.helpers.0.modules_dep = true
          config.0.helpers.0.network = true
          config.0.helpers.0.updatedb_disabled = true
          config.0.kernel = linode/grub2
          config.0.label = My Debian 9 Disk Profile
          config.0.memory_limit = 0
          config.0.root_device = /dev/root
          config.0.run_level = default
          config.0.virt_mode = paravirt
          disk.# = 2
          disk.0.authorized_keys.# = 0
          disk.0.filesystem = ext4
          disk.0.id = 24170011
          disk.0.image =
          disk.0.label = Debian 9 Disk
          disk.0.read_only = false
          disk.0.root_pass =
          disk.0.size = 50688
          disk.0.stackscript_data.% = 0
          disk.0.stackscript_id = 0
          disk.1.authorized_keys.# = 0
          disk.1.filesystem = swap
          disk.1.id = 24170012
          disk.1.image =
          disk.1.label = 512 MB Swap Image
          disk.1.read_only = false
          disk.1.root_pass =
          disk.1.size = 512
          disk.1.stackscript_data.% = 0
          disk.1.stackscript_id = 0
          group = Terraform
          ip_address = 192.0.2.2
          ipv4.# = 1
          ipv4.1835604989 = 192.0.2.2
          ipv6 = 2600:3c03::f03c:91ff:fef6:3ebe/64
          label = terraform-import
          private_ip = false
          region = us-east
          specs.# = 1
          specs.0.disk = 51200
          specs.0.memory = 2048
          specs.0.transfer = 2000
          specs.0.vcpus = 1
          status = running
          swap_size = 512
          type = g6-standard-1
          watchdog_enabled = true
        
        

        You will use this information in the next section.

        Note

        There is a current bug in the Linode Terraform provider that causes the Linode’s root_device configuration to display an import value of /dev/root, instead of /dev/sda. This is visible in the example output above: config.0.root_device = /dev/root. However, the correct disk, /dev/sda, is in fact targeted. For this reason, when running the terraform plan or the terraform apply commands, the output will display config.0.root_device: "/dev/root" => "/dev/sda".

        You can follow the corresponding GitHub issue for more details.

      Fill In Your Linode’s Configuration Data

      As mentioned in the Terraform’s Import Command section, you must manually create your resource configurations when importing existing infrastructure.

      1. Fill in the configuration values for the linode_instance resource block. In the example below, the necessary values were collected from the output of the terraform show command applied in Step 2 of the Import Your Linode to Terraform section. The file’s comments indicate the corresponding keys used to determine the values for the linode_instance configuration block.

        linode_instance_import.tf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        
        provider "linode" {
            token = "a12b3c4e..."
        }
        
        resource "linode_instance" "example_label" {
            label = "terraform-import" #label
            region = "us-east"         #region
            type = "g6-standard-1"     #type
            config {
                label = "My Debian 9 Disk Profile"     #config.0.label
                kernel = "linode/grub2"                #config.0.kernel
                root_device = "/dev/sda"               #config.0.root_device
                devices {
                    sda = {
                        disk_label = "Debian 9 Disk"    #config.0.devices.0.sda.0.disk_label
                    }
                    sdb = {
                        disk_label = "512 MB Swap Image" #config.0.devices.0.sdb.0.disk_label
                    }
                }
            }
            disk {
                label = "Debian 9 Disk"      #disk.0.label
                size = "50688"               #disk.0.size
            }
            disk {
                label = "512 MB Swap Image"  #disk.1.label
                size = "512"                 #disk.1.size
            }
        }
            

        Note

        If your Linode uses more than two disks (for instance, if you have attached a Block Storage Volume), you will need to add those disks to your Linode resource configuration block. In order to add a disk, you must add the disk to the devices stanza and create an additional disk stanza.

        Note

        If you have more than one configuration profile, you must choose which profile to boot from with the boot_config_label argument. For example:

        resource "linode_instance" "example_label" {
            boot_config_label = "My Debian 9 Disk Profile"
        ...
        
      2. To check for errors in your configuration, run the plan command:

        terraform plan
        

        terraform plan shows you the changes that would take place if you were to apply the configurations with a terraform apply. Running terraform plan is a good way to determine if the configuration you provided is exact enough for Terraform to take over the management of your Linode.

        Note

        Running terraform plan will display any changes that will be applied to your existing infrastructure based on your configuration file(s). However, you will not be notified about the addition and removal of disks with terraform plan. For this reason, it is vital that the values you include in your linode_instance resource configuration block match the values generated from running the terraform show command.

      3. Once you have verified the configurations you provided in the linode_instance resource block, you are ready to begin managing your Linode instance with Terraform. Any changes or updates can be made by updating your linode_instance_import.tf file, then verifying the changes with the terrform plan command, and then finally applying the changes with the terraform apply command.

        For more available configuration options, visit the Linode Instance Terraform documentation.

      Import a Domain to Terraform

      Retrieve Your Domain’s ID

      1. Using the Linode CLI, retrieve a list of all your domains to find the ID of the domain you would like to manage under Terraform:

        linode-cli domains list --json --pretty
        

        You should see output like the following:

          
        [
          {
            "domain": "import-example.com",
            "id": 1157521,
            "soa_email": "webmaster@import-example.com",
            "status": "active",
            "type": "master"
          }
        ]
        
        

        Find the domain you would like to import and copy down the ID. You will need this ID to import your domain to Terraform.

      Create an Empty Resource Configuration

      1. Ensure you are in your Terraform project directory. Create a Terraform configuration file to manage the domain you will import in the next section. Your file can be named anything you like, but must end in .tf. Add a Linode provider block with your API access token and an empty linode_domain resource configuration block to the file:

        domain_import.tf
        1
        2
        3
        4
        5
        
        provider "linode" {
            token = "Your API Token"
        }
        
        resource "linode_domain" "example_label" {}

      Import Your Domain to Terraform

      1. Run the import command, supplying the linode_domain resource’s label, and the domain ID that was retrieved in the Retrieve Your Domain’s ID section:

        terraform import linode_domain.example_label domainID
        

        You should see output similar to the following:

          
        linode_domain.example_label: Importing from ID "1157521"...
        linode_domain.example_label: Import complete!
          Imported linode_domain (ID: 1157521)
        linode_domain.example_label: Refreshing state... (ID: 1157521)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        

        This command will create a terraform.tfstate file with information about your domain. You will use this information to fill out your resource configuration.

      2. To view the information created by terraform import, run the show command. This command will display a list of key-value pairs representing information about the imported domain:

        terraform show
        

        You should see output like the following:

          
        linode_domain.example_label:
          id = 1157521
          description =
          domain = import-example.com
          expire_sec = 0
          group =
          master_ips.# = 0
          refresh_sec = 0
          retry_sec = 0
          soa_email = webmaster@import-example.com
          status = active
          ttl_sec = 0
          type = master
        
        

      Fill In Your Domain’s Configuration Data

      As mentioned in the Terraform’s Import Command section, you must manually create your resource configurations when importing existing infrastructure.

      1. Fill in the configuration values for the linode_domain resource block. The necessary values for the example resource configuration file were collected from the output of the terraform show command applied in Step 2 of the Import Your Domain to Terraform section.

        linode_domain_example.tf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        provider "linode" {
            token = "1a2b3c..."
        }
        
        resource "linode_domain" "example_label" {
            domain = "import-example.com"
            soa_email = "webmaster@import-example.com"
            type = "master"
        }
            

        Note

        If your Domain type is slave then you’ll need to include a master_ips argument with values set to the IP addresses that represent the Master DNS for your domain.

      2. Check for errors in your configuration by running the plan command:

        terraform plan
        

        terraform plan shows you the changes that would take place if you were to apply the configurations with the terraform apply command. Running terraform plan should result in Terraform displaying that no changes are to be made.

      3. Once you have verified the configurations you provided in the linode_domain block, you are ready to begin managing your domain with Terraform. Any changes or updates can be made by updating your linode_domain_example.tf file, then verifying the changes with the terrform plan command, and then finally applying the changes with the terraform apply command.

        For more available configuration options, visit the Linode Domain Terraform documentation.

      Import a Block Storage Volume to Terraform

      Retrieve Your Block Storage Volume’s ID

      1. Using the Linode CLI, retrieve a list of all your volumes to find the ID of the Block Storage Volume you would like to manage under Terraform:

        linode-cli volumes list --json --pretty
        

        You should see output similar to the following:

          
        [
          {
            "id": 17045,
            "label": "import-example",
            "linode_id": 11426126,
            "region": "us-east",
            "size": 20,
            "status": "active"
          }
        ]
        
        

        Find the Block Storage Volume you would like to import and copy down the ID. You will use this ID to import your volume to Terraform.

      Create an Empty Resource Configuration

      1. Ensure you are in your Terraform project directory. Create a Terraform configuration file to manage the Block Storage Volume you will import in the next section. Your file can be named anything you like, but must end in .tf. Add a Linode provider block with your API access token and an empty linode_volume resource configuration block to the file:

        linode_volume_example.tf
        1
        2
        3
        4
        5
        
        provider "linode" {
            token = "Your API Token"
        }
        
        resource "linode_volume" "example_label" {}

      Import Your Volume to Terraform

      1. Run the import command, supplying the linode_volume resource’s label, and the volume ID that was retrieved in the Retrieve Your Block Storage Volume’s ID section:

        terraform import linode_volume.example_label volumeID
        

        You should see output similar to the following:

          
        linode_volume.example_label: Importing from ID "17045"...
        linode_volume.example_label: Import complete!
          Imported linode_volume (ID: 17045)
        linode_volume.example_label: Refreshing state... (ID: 17045)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        

        This command will create a terraform.tfstate file with information about your Volume. You will use this information to fill out your resource configuration.

      2. To view the information created by terraform import, run the show command. This command will display a list of key-value pairs representing information about the imported Volume:

        terraform show
        

        You should see output like the following:

          
        linode_volume.example_label:
          id = 17045
          filesystem_path = /dev/disk/by-id/scsi-0Linode_Volume_import-example
          label = import-example
          linode_id = 11426126
          region = us-east
          size = "20"
          status = active
        
        

      Fill In Your Volume’s Configuration Data

      As mentioned in the Terraform’s Import Command section, you must manually create your resource configurations when importing existing infrastructure.

      1. Fill in the configuration values for the linode_volume resource block. The necessary values for the example resource configuration file were collected from the output of the terraform show command applied in Step 2 of the Import Your Volume to Terraform section:

        linode_volume_example.tf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        provider "linode" {
            token = "1a2b3c..."
        }
        
        resource "linode_volume" "example_label" {
            label = "import-example"
            region = "us-east"
            size = "20"
        }
            

        Note

        Though it is not required, it’s a good idea to include a configuration for the size of the volume so that it can be managed more easily should you ever choose to expand the Volume. It is not possible to reduce the size of a volume.

      2. Check for errors in your configuration by running the plan command:

        terraform plan
        

        terraform plan shows you the changes that would take place if you were to apply the configurations with the terraform apply command. Running terraform plan should result in Terraform displaying that no changes are to be made.

      3. Once you have verified the configurations you provided in the linode_volume block, you are ready to begin managing your Block Storage Volume with Terraform. Any changes or updates can be made by updating your linode_volume_example.tf file, then verifying the changes with the terrform plan command, and then finally applying the changes with the terraform apply command.

        For more optional configuration options, visit the Linode Volume Terraform documentation.

      Import a NodeBalancer to Terraform

      Configuring Linode NodeBalancers with Terraform requires three separate resource configuration blocks: one to create the NodeBalancer, a second for the NodeBalancer Configuration, and a third for the NodeBalancer Nodes.

      Retrieve Your NodeBalancer, NodeBalancer Config, NodeBalancer Node IDs

      1. Using the Linode CLI, retrieve a list of all your NodeBalancers to find the ID of the NodeBalancer you would like to manage under Terraform:

        linode-cli nodebalancers list --json --pretty
        

        You should see output similar to the following:

          
        [
          {
            "client_conn_throttle": 0,
            "hostname": "nb-192-0-2-3.newark.nodebalancer.linode.com",
            "id": 40721,
            "ipv4": "192.0.2.3",
            "ipv6": "2600:3c03:1::68ed:945f",
            "label": "terraform-example",
            "region": "us-east"
          }
        ]
        
        

        Find the NodeBalancer you would like to import and copy down the ID. You will use this ID to import your NodeBalancer to Terraform.

      2. Retrieve your NodeBalancer configuration by supplying the ID of the NodeBalancer you retrieved in the previous step:

        linode-cli nodebalancers configs-list 40721 --json --pretty
        

        You should see output similar to the following:

          
        [
          {
            "algorithm": "roundrobin",
            "check_passive": true,
            "cipher_suite": "recommended",
            "id": 35876,
            "port": 80,
            "protocol": "http",
            "ssl_commonname": "",
            "ssl_fingerprint": "",
            "stickiness": "table"
          }
        ]
        
        

        Copy down the ID of your NodeBalancer configuration, you will use it to import your NodeBalancer configuration to Terraform.

      3. Retrieve a list of Nodes corresponding to your NodeBalancer to find the label and address of your NodeBalancer Nodes. Supply the ID of your NodeBalancer as the first argument and the ID of your NodeBalancer configuration as the second:

        linode-cli nodebalancers nodes-list 40721 35876 --json --pretty
        

        You should see output like the following:

          
        [
          {
            "address": "192.168.214.37:80",
            "id": 327539,
            "label": "terraform-import",
            "mode": "accept",
            "status": "UP",
            "weight": 100
          }
        ]
        
        

        If you are importing a NodeBalancer, chances are your output lists more than one Node. Copy down the IDs of each Node. You will use them to import your Nodes to Terraform.

      Create Empty Resource Configurations

      1. Ensure you are in your Terraform project directory. Create a Terraform configuration file to manage the NodeBalancer you will import in the next section. Your file can be named anything you like, but must end in .tf.

        Add a Linode provider block with your API access token and empty linode_nodebalancer, linode_nodebalancer_config, and linode_nodebalancer_node resource configuration blocks to the file. Be sure to give the resources appropriate labels. These labels will be used to reference the resources locally within Terraform:

        linode_nodebalancer_example.tf
        1
        2
        3
        4
        5
        6
        7
        8
        9
        
        provider "linode" {
            token = "Your API Token"
        }
        
        resource "linode_nodebalancer" "example_nodebalancer_label" {}
        
        resource "linode_nodebalancer_config" "example_nodebalancer_config_label" {}
        
        resource "linode_nodebalancer_node" "example_nodebalancer_node_label" {}

        If you have more than one NodeBalancer Configuration, you will need to supply multiple linode_nodebalancer_config resource blocks with different labels. The same is true for each NodeBalancer Node requiring an additional linode_nodebalancer_node block.

      Import Your NodeBalancer, NodeBalancer Configuration, and NodeBalancer Nodes to Terraform

      1. Run the import command for your NodeBalancer, supplying your local label and the ID of your NodeBalancer as the last parameter.

        terraform import linode_nodebalancer.example_nodebalancer_label nodebalancerID
        

        You should see output similar to the following:

          
        linode_nodebalancer.example_nodebalancer_label: Importing from ID "40721"...
        linode_nodebalancer.example_nodebalancer_label: Import complete!
          Imported linode_nodebalancer (ID: 40721)
        linode_nodebalancer.example_nodebalancer_label: Refreshing state... (ID: 40721)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        
      2. Run the import command for your NodeBalancer configuration, supplying your local label, and the ID of your NodeBalancer and the ID of your NodeBalancer configuration separated by commas as the last argument.

        terraform import linode_nodebalancer_config.example_nodebalancer_config_label nodebalancerID,nodebalancerconfigID
        

        You should see output similar to the following:

          
        linode_nodebalancer_config.example_nodebalancer_config_label: Importing from ID "40721,35876"...
        linode_nodebalancer_config.example_nodebalancer_config_label: Import complete!
          Imported linode_nodebalancer_config (ID: 35876)
        linode_nodebalancer_config.example_nodebalancer_config_label: Refreshing state... (ID: 35876)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        
      3. Run the import command for you NodeBalancer Nodes, supplying your local label, and the ID of your NodeBalancer, the ID of your NodeBalancer Configuration, and your NodeBalancer Node, separated by commas, as the last argument.

        terraform import linode_nodebalancer_node.example_nodebalancer_node_label nodebalancerID,nodebalancerconfigID,nodebalancernodeID
        

        You should see output like the following:

          
        linode_nodebalancer_node.example_nodebalancer_node_label: Importing from ID "40721,35876,327539"...
        linode_nodebalancer_node.example_nodebalancer_node_label: Import complete!
          Imported linode_nodebalancer_node (ID: 327539)
        linode_nodebalancer_node.example_nodebalancer_node_label: Refreshing state... (ID: 327539)
        
        Import successful!
        
        The resources that were imported are shown above. These resources are now in
        your Terraform state and will henceforth be managed by Terraform.
        
        
      4. Running terraform import creates a terraform.tfstate file with information about your NodeBalancer. You will use this information to fill out your resource configuration. To view the information created by terraform import, run the show command:

        terraform show
        

        You should see output like the following:

          
        linode_nodebalancer.example_nodebalancer_label:
          id = 40721
          client_conn_throttle = 0
          created = 2018-11-16T20:21:03Z
          hostname = nb-192-0-2-3.newark.nodebalancer.linode.com
          ipv4 = 192.0.2.3
          ipv6 = 2600:3c03:1::68ed:945f
          label = terraform-example
          region = us-east
          transfer.% = 3
          transfer.in = 0.013627052307128906
          transfer.out = 0.0015048980712890625
          transfer.total = 0.015131950378417969
          updated = 2018-11-16T20:21:03Z
        
        linode_nodebalancer_config.example_nodebalancer_config_label:
          id = 35876
          algorithm = roundrobin
          check = none
          check_attempts = 2
          check_body =
          check_interval = 5
          check_passive = true
          check_path =
          check_timeout = 3
          cipher_suite = recommended
          node_status.% = 2
          node_status.down = 0
          node_status.up = 1
          nodebalancer_id = 40721
          port = 80
          protocol = http
          ssl_commonname =
          ssl_fingerprint =
          ssl_key =
          stickiness = table
        
        linode_nodebalancer_node.example_nodebalancer_node_label:
          id = 327539
          address = 192.168.214.37:80
          config_id = 35876
          label = terraform-import
          mode = accept
          nodebalancer_id = 40721
          status = UP
          weight = 100
        
        

      Fill In Your NodeBalancer’s Configuration Data

      As mentioned in the Terraform’s Import Command section, you must manually create your resource configurations when importing existing infrastructure.

      1. Fill in the configuration values for all three NodeBalancer resource configuration blocks. The necessary values for the example resource configuration file were collected from the output of the terraform show command applied in Step 4 of the Import Your NodeBalancer, NodeBalancer Configuration, and NodeBalancer Nodes to Terraform section:
      linode_nodebalancer_example.tf
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      
      provider "linode" {
          token = "1a2b3c..."
      }
      
      resource "linode_nodebalancer" "nodebalancer_import" {
          label = "terraform-example"
          region = "us-east"
      }
      
      resource "linode_nodebalancer_config" "nodebalancer_config_import" {
          nodebalancer_id = "40721"
      }
      
      resource "linode_nodebalancer_node" "nodebalancer_node_import" {
          label = "terraform-import"
          address = "192.168.214.37:80"
          nodebalancer_id = "40721"
          config_id = "35876"
      }
      1. Check for errors in your configuration by running the plan command:

        terraform plan
        

        terraform plan shows you the changes that would take place if you were to apply the configurations with the terraform apply command. Running terraform plan should result in Terraform displaying that no changes are to be made.

      2. Once you have verified the configurations you provided in all three NodeBalancer configuration blocks, you are ready to begin managing your NodeBalancers with Terraform. Any changes or updates can be made by updating your linode_nodebalancer_example.tf file, then verifying the changes with the terrform plan command, and finally, applying the changes with the terraform apply command.

        For more available configuration options, visit the Linode NodeBalancer, Linode NodeBalancer Config, and Linode NodeBalancer Node Terraform documentation.

      Next Steps

      You can follow a process similar to what has been outlined in this guide to begin importing other pieces of your Linode infrastructure such as images, SSH keys, access tokens, and StackScripts. Check out the links in the More Information section below for helpful information.

      More Information

      You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

      Find answers, ask questions, and help others.

      This guide is published under a CC BY-ND 4.0 license.



      Source link