diff --git a/google/resource_dns_record_set.go b/google/resource_dns_record_set.go index 71943a03..0c4c6fe2 100644 --- a/google/resource_dns_record_set.go +++ b/google/resource_dns_record_set.go @@ -95,7 +95,7 @@ func resourceDnsRecordSetCreate(d *schema.ResourceData, meta interface{}) error var deletions []*dns.ResourceRecordSet for _, record := range res.Rrsets { - if record.Type != "NS" { + if record.Type != "NS" || record.Name != d.Get("name").(string) { continue } deletions = append(deletions, record) @@ -164,14 +164,6 @@ func resourceDnsRecordSetRead(d *schema.ResourceData, meta interface{}) error { } func resourceDnsRecordSetDelete(d *schema.ResourceData, meta interface{}) error { - - // NS records must always have a value, so we short-circuit delete - // this allows terraform delete to work, but may have unexpected - // side-effects when deleting just that record set. - if d.Get("type").(string) == "NS" { - log.Println("[DEBUG] NS records can't be deleted due to API restrictions, so they're being left in place. See https://www.terraform.io/docs/providers/google/r/dns_record_set.html for more information.") - return nil - } config := meta.(*Config) project, err := getProject(d, config) @@ -181,6 +173,29 @@ func resourceDnsRecordSetDelete(d *schema.ResourceData, meta interface{}) error zone := d.Get("managed_zone").(string) + // NS records must always have a value, so we short-circuit delete + // this allows terraform delete to work, but may have unexpected + // side-effects when deleting just that record set. + // Unfortunately, you can set NS records on subdomains, and those + // CAN and MUST be deleted, so we need to retrieve the managed zone, + // check if what we're looking at is a subdomain, and only not delete + // if it's not actually a subdomain + var domain string + if d.Get("type").(string) == "NS" { + if domain == "" { + mz, err := config.clientDns.ManagedZones.Get(project, zone).Do() + if err != nil { + return fmt.Errorf("Error retrieving managed zone %q from %q: %s", zone, project, err) + } + domain = mz.DnsName + } + + if domain == d.Get("name").(string) { + log.Println("[DEBUG] NS records can't be deleted due to API restrictions, so they're being left in place. See https://www.terraform.io/docs/providers/google/r/dns_record_set.html for more information.") + return nil + } + } + // Build the change chg := &dns.Change{ Deletions: []*dns.ResourceRecordSet{ diff --git a/google/resource_dns_record_set_test.go b/google/resource_dns_record_set_test.go index 94aac3ef..f4553634 100644 --- a/google/resource_dns_record_set_test.go +++ b/google/resource_dns_record_set_test.go @@ -108,6 +108,24 @@ func TestAccDnsRecordSet_ns(t *testing.T) { }) } +func TestAccDnsRecordSet_nestedNS(t *testing.T) { + zoneName := fmt.Sprintf("dnszone-test-ns-%s", acctest.RandString(10)) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDnsRecordSetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDnsRecordSet_nestedNS(zoneName, 300), + Check: resource.ComposeTestCheckFunc( + testAccCheckDnsRecordSetExists( + "google_dns_record_set.foobar", zoneName), + ), + }, + }, + }) +} + func testAccCheckDnsRecordSetDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) @@ -192,6 +210,23 @@ func testAccDnsRecordSet_ns(name string, ttl int) string { `, name, ttl) } +func testAccDnsRecordSet_nestedNS(name string, ttl int) string { + return fmt.Sprintf(` + resource "google_dns_managed_zone" "parent-zone" { + name = "%s" + dns_name = "hashicorptest.com." + description = "Test Description" + } + resource "google_dns_record_set" "foobar" { + managed_zone = "${google_dns_managed_zone.parent-zone.name}" + name = "nested.hashicorptest.com." + type = "NS" + rrdatas = ["ns.hashicorp.services.", "ns2.hashicorp.services."] + ttl = %d + } + `, name, ttl) +} + func testAccDnsRecordSet_bigChange(zoneName string, ttl int) string { return fmt.Sprintf(` resource "google_dns_managed_zone" "parent-zone" {