dnsimple / terraform-provider-dnsimple

Terraform DNSimple provider.
https://www.terraform.io/docs/providers/dnsimple/
Mozilla Public License 2.0
21 stars 20 forks source link

DNSimple resources are incompatible with AWS resources #8

Closed tmaier closed 2 years ago

tmaier commented 6 years ago

Suppose you want to create an ACM certificate using the https://www.terraform.io/docs/providers/aws/r/acm_certificate.html resource.

It would output

domain_name and resource_record_name are full FQDNs.

DNSimple needs two parameters domain + subdomain.

Please change DNSimple in order to be able to specify the intended FQDN instead of the two parameters

nbering commented 6 years ago

My outside opinion is that Terraform's providers shouldn't necessarily have to guarantee compatibility with one another. The matrix of possible combinations of services just in the DNS+Cloud Provider space alone would make it very difficult to manage.

And probably not desirable either, since for DNSimple customers, this interface is similar across all tooling that uses their API.

Here's a little freebie I whipped up for my own ACM certificates. It's ugly as heck, but it worked for me.

I wrote this a while ago, so I couldn't tell you all the nitty-gritty details about how it works. The only thing I can explain well is that the regular expression is tracking on the trailing ., then following the . from the top-level domain, and finally uses the . from the subdomain to anchor the regex and find the name for the record. A similar thing is done to find the record's domain.

I haven't tested this with nested subdomains like one.two.example.com. They might be a problem for this scheme, but should work with adjustments to the regular expression.

resource "aws_acm_certificate" "www" {
  provider          = "aws.us-east"
  domain_name       = "www.example.com"
  validation_method = "DNS"
}

resource "dnsimple_record" "www-verify" {
  type   = "${aws_acm_certificate.www.domain_validation_options.0.resource_record_type}"
  name   = "${replace(aws_acm_certificate.www.domain_validation_options.0.resource_record_name, "/(.*?)\\.\\w+\\.\\w+\\.$/", "$1")}"
  domain = "${replace(aws_acm_certificate.www.domain_validation_options.0.resource_record_name, "/.*?(\\w+\\.\\w+)\\.$/", "$1")}"
  value  = "${replace(aws_acm_certificate.www.domain_validation_options.0.resource_record_value, "/(.*)\\.$/", "$1")}"
  ttl    = 60
}
boomshadow commented 4 years ago

The DNSimple provider is mostly compatible. The issue I run into is where the AWS Provider outputs DNS names with a trailing dot, which DNSimple does not accept. I get 400 Validation failed because the value being sent in from my other resources has a trailing dot.

There's also the issue where the DNS name being passed is the FQDN and DNSimple only expects the specific subdomain, without the root domain. Which makes the record look like this over at DNSimple: _e12345d1234567890123f1e17d9b4af73.mydomain.com.mydomain.com

I am able to create a wildcard ACM certificate, with DNS validation by performing terraform trim function on the values in order to make things the right format.

My code looks like this. This works successfully:

resource "aws_acm_certificate" "main_wildcard" {
  domain_name       = "*.mydomain.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "dnsimple_record" "main_wildcard_validation" {
  domain = "mydomain.com"
  name   = trim(aws_acm_certificate.main_wildcard.domain_validation_options.0.resource_record_name, ".mydomain.com.")
  type   = aws_acm_certificate.main_wildcard.domain_validation_options.0.resource_record_type
  value  = trim(aws_acm_certificate.main_wildcard.domain_validation_options.0.resource_record_value, ".")
  ttl    = 60
}

resource "aws_acm_certificate_validation" "main_wildcard" {
  certificate_arn         = aws_acm_certificate.main_wildcard.arn
  validation_record_fqdns = ["${dnsimple_record.main_wildcard_validation.hostname}"]
}
weppos commented 2 years ago

I am closing this issue, as we have no plan to adjust the format of our provider to be specifically targeting another provider. It would eventually make the maintenance impossible due to the tight coupling with other company's choices.

For instance, AWS and Google Cloud providers may evolve differently. We will find ourselves in an uncomfortable position of designing our provider to be compatible with either one provider or the other.

The compatibility can be achieved by either implementing a mapping function (as in the comment above), or by implementing a custom resource and using our go-client directly.

Finally, we have made significant changes to our provider and introduced a newly designed dnsimple_zone_record resource that will replace the dnsimple_record resource, originally built around our v1 API that exposed zone records as domain records.

We will continue to monitor best practices around providers and follow common conventions, whenever applicable.