Namecheap Terraform Provider

repository·master·Indexed 41 days ago

https://github.com/namecheap/terraform-provider-namecheap

A Terraform provider for managing Namecheap domain DNS configurations, including automated management of domain records, nameservers, and account balances. It provides resources like namecheap_domain_records and namecheap_domain_host_record, as well as data sources for retrieving domain information and account funds.

Tokens
21.3K
Snippets
57
Records
90
Agent score
45%

What's inside Namecheap

  1. Manage DNS host records with namecheap_domain_records

    master

    The namecheap_domain_records resource manages the DNS host records of a domain or delegates the domain to custom nameservers.

    Management Modes

    You can control how the resource interacts with existing DNS records using the mode argument:

    • MERGE (default): The provider manages only the specific records you declare in your Terraform configuration. Existing records not mentioned in your code remain untouched.
    • OVERWRITE: The provider owns the entire DNS zone. Warning: This mode will permanently delete any existing records (including those created manually or by other tools) that are not explicitly defined in your Terraform configuration.

    Since v2.5.0, the provider includes safety warnings during terraform plan and terraform apply when using OVERWRITE mode, providing ready-to-paste record blocks for any live records that would be deleted.

    resource "namecheap_domain_records" "my-domain-com" {
      domain = "my-domain.com"
      email_type = "NONE"
    
      record {
        hostname = "blog"
        type = "A"
        address = "10.11.12.13"
      }
    }
  2. Handle MX records and Email settings

    master

    MX and MXE records are tied to the domain's EmailType. This resource does not manage EmailType.

    Before creating MX records with this resource, you must set the email_type using the namecheap_domain_records resource or via the Namecheap dashboard. If the EmailType is not correctly configured, the API will reject the write.

    Limitation: Domains using Private Email or Google Workspace cannot be managed with namecheap_domain_host_record yet. For these domains, you must use namecheap_domain_records.

  3. Understand dependency management and integrity

    master

    The project uses Go modules for reproducible and secure dependency management.

    • Pinning: Every direct and indirect Go dependency is declared in go.mod with an exact version or pseudo-version.
    • Integrity: go.sum stores cryptographic hashes for every module. The build will fail if a re-fetched module does not match the recorded hash.
    • Toolchain: The Go toolchain version is pinned in go.mod (currently go 1.25.9).
    • Verification: CI enforces integrity using go mod verify (rehashes cache against go.sum) and go mod tidy (ensures go.mod/go.sum drift is zero).
  4. How runner lifecycle and hygiene sweeps work

    master

    To maintain security and prevent state carry-over between tests, the provider uses a strict lifecycle and hygiene model:

    • Per-run Lifecycle: The start-runner action launches a fresh instance for every acceptance run, and stop-runner terminates it immediately after. A max-lifetime-minutes TTL (default 360) acts as a self-destruct backstop.
    • Hygiene Sweeps: The script scripts/hygiene-sweep.sh performs two passes:
      • Pre-pass: Lays out the JOB_HOME.
      • Post-pass: Runs with if: always() to ensure that even if a job fails, all code, environment variables, and secrets are wiped from the disk before the instance is terminated.
    • Workspace Freshness: Initial workspace cleanliness is guaranteed by actions/checkout using the clean: true setting.
  5. Manage subdomains using the hostname field

    master

    The Namecheap API does not support managing FreeDNS subdomain zones (e.g., sub.example.com) as independent entities. The domain field in your configuration must always be a registered root domain. To create records for a subdomain, do not attempt to manage the subdomain as a separate zone; instead, use the hostname field within the record block to specify the subdomain prefix.

    # Example of creating a record for sub.example.com
    # domain must be the root domain
    resource "namecheap_domain_records" "example" {
      domain = "example.com"
    
      record {
        hostname = "sub"
        value    = "1.2.3.4"
        type     = "A"
      }
    }
  6. Manage Namecheap domain records with MERGE and OVERWRITE modes

    master

    When managing DNS records via the Namecheap provider, you can choose between two modes to control how Terraform interacts with existing records:

    • MERGE mode: Adds or updates specific records without affecting existing ones. This is the recommended mode if you have records that were created manually or via other tools (like SRV or Dynamic DNS records which are restricted by the Namecheap API) and you want Terraform to manage only a subset of the records.
    • OVERWRITE mode: Replaces the entire set of records for the domain with only the ones defined in your Terraform configuration.
  7. Understand the self-hosted runner supply chain

    master

    The acceptance tests for this provider run on fresh EC2 instances launched via the namecheap/ec2-github-runner action. This ensures a clean environment for every run. Key characteristics include:

    • Runner Versioning: Controlled via SHA-pinned actions (currently using actions/runner v2.335.1 and externals/node24).
    • Security Gating: Secret-bound EC2 jobs (like start-runner and acceptance_test) are gated to run only on trusted code (same-repo pull requests, pushes to master, or manual dispatch). They never run for Dependabot or fork-based pull requests to prevent secret exposure.
    • Concurrency: Access to the repository's dedicated Elastic IP (EIP) is serialized using the ahmadnassri/action-workflow-queue action to prevent multiple runners from attempting to use the same IP simultaneously.
  8. How to compare TLD prices in HCL

    master

    Because all monetary attributes are exported as strings to prevent IEEE-754 floating-point precision errors, you must use tonumber() when performing comparisons in HCL.

    To find the cheapest TLD among a set of candidates, use for_each to fetch prices, map them to numbers in a local variable, and use the min() function. It is recommended to use sort() on the resulting list of TLDs to ensure deterministic tie-breaking when multiple TLDs share the same lowest price.

    data "namecheap_tld_pricing" "candidates" {
      for_each = toset(["com", "net", "org"])
    
      tld    = each.key
      action = "REGISTER"
      years  = 1
    }
    
    locals {
      prices         = { for tld, p in data.namecheap_tld_pricing.candidates : tld => tonumber(p.price) }
      cheapest_price = min(values(local.prices)...)
    
      # sort() makes the tie-break deterministic
      cheapest_tlds = sort([for tld, price in local.prices : tld if price == local.cheapest_price])
    }
    
    output "cheapest_tld" {
      value = local.cheapest_tlds[0]
    }
  9. Compare namecheap_domain_host_record and namecheap_domain_records

    master

    Choosing the right resource depends on your management strategy:

    • Use namecheap_domain_host_record for granular control. Use this when records are managed independently or by different entities. It manages one record at a time.
    • Use namecheap_domain_records for zone-level control. Use this when a single configuration should own the entire DNS zone (similar to a zone-file style) and ensure no other records exist.

    CRITICAL: Do not use both resources on the same domain. They will conflict, leading to records being deleted or ownership fights.

  10. Choose between MERGE and OVERWRITE modes

    master

    The mode argument determines how Terraform interacts with existing DNS records on the Namecheap domain.

    MERGE (Default)

    Records defined in Terraform are added to the existing DNS zone. Existing records created manually or via other tools are preserved. If a resource is removed from Terraform, only the records managed by that resource are deleted.

    Note: Using multiple Terraform resources with the same domain in MERGE mode can cause race conditions. Use mode = "MERGE" explicitly to be safe.

    OVERWRITE (Destructive)

    Warning: This mode replaces the entire DNS zone. Any existing records not explicitly defined in your Terraform configuration will be permanently deleted.

    To prevent accidental deletion, the provider includes safety warnings:

    • At terraform plan: A warning is emitted if a live record is not in your configuration.
    • At terraform apply: A final warning is emitted before the destructive write. The warning includes a ready-to-paste record { ... } block for every record about to be deleted, allowing you to easily adopt them into your config.
    # Example of MERGE mode for managing specific subdomains independently
    resource "namecheap_domain_records" "blog-my-domain-com" {
      domain = "my-domain.com"
      mode = "MERGE"
      
      record {
        hostname = "blog"
        type = "A"
        address = "11.22.33.44"
      }
    }
  11. Review vulnerability and license scanning policies

    master

    The repository employs automated scanning to detect vulnerabilities, misconfigurations, secrets, and license violations.

    Vulnerability Scanning

    • Trivy: Runs on every code-touching push/PR. It scans for vuln, misconfig, secret, and license. It gates on CRITICAL and HIGH severities, but ignores unfixable advisories (ignore-unfixed: true).
    • govulncheck: A Go-native scanner that performs call-graph reachability analysis. It fails the build only if a vulnerable symbol is actually reachable from the module's code, reducing noise from unused dependencies.

    License Policy

    Licenses are managed via trivy.yaml. The project uses a denylist approach. The following copyleft/source-available licenses are rejected:

    • GPL-2.0
    • GPL-3.0
    • AGPL-1.0
    • AGPL-3.0
    • LGPL-3.0
    • SSPL-1.0

    Exception Workflow: To use a rejected license, open a PR adding a scoped ignored-licenses: entry to trivy.yaml with a justification and approval from an external reviewer.