diff --git a/.changelog/5495.txt b/.changelog/5495.txt new file mode 100644 index 00000000000..4fc6c20d494 --- /dev/null +++ b/.changelog/5495.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +container: promoted `dns_config` field of `google_container_cluster` to GA +``` diff --git a/google/resource_container_cluster.go b/google/resource_container_cluster.go index 41b037e181e..8af4f5344a0 100644 --- a/google/resource_container_cluster.go +++ b/google/resource_container_cluster.go @@ -1056,6 +1056,36 @@ func resourceContainerCluster() *schema.Resource { }, }, }, + "dns_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ForceNew: true, + Description: `Configuration for Cloud DNS for Kubernetes Engine.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cluster_dns": { + Type: schema.TypeString, + Default: "PROVIDER_UNSPECIFIED", + ValidateFunc: validation.StringInSlice([]string{"PROVIDER_UNSPECIFIED", "PLATFORM_DEFAULT", "CLOUD_DNS"}, false), + Description: `Which in-cluster DNS provider should be used.`, + Optional: true, + }, + "cluster_dns_scope": { + Type: schema.TypeString, + Default: "DNS_SCOPE_UNSPECIFIED", + ValidateFunc: validation.StringInSlice([]string{"DNS_SCOPE_UNSPECIFIED", "CLUSTER_SCOPE", "VPC_SCOPE"}, false), + Description: `The scope of access to cluster DNS records.`, + Optional: true, + }, + "cluster_dns_domain": { + Type: schema.TypeString, + Description: `The suffix used for all cluster service records.`, + Optional: true, + }, + }, + }, + }, }, } } @@ -1175,6 +1205,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er DefaultSnatStatus: expandDefaultSnatStatus(d.Get("default_snat_status")), DatapathProvider: d.Get("datapath_provider").(string), PrivateIpv6GoogleAccess: d.Get("private_ipv6_google_access").(string), + DnsConfig: expandDnsConfig(d.Get("dns_config")), }, MasterAuth: expandMasterAuth(d.Get("master_auth")), ConfidentialNodes: expandConfidentialNodes(d.Get("confidential_nodes")), @@ -1597,7 +1628,9 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("resource_usage_export_config", flattenResourceUsageExportConfig(cluster.ResourceUsageExportConfig)); err != nil { return err } - + if err := d.Set("dns_config", flattenDnsConfig(cluster.NetworkConfig.DnsConfig)); err != nil { + return err + } if err := d.Set("logging_config", flattenContainerClusterLoggingConfig(cluster.LoggingConfig)); err != nil { return err } @@ -2939,6 +2972,20 @@ func expandResourceUsageExportConfig(configured interface{}) *container.Resource return result } +func expandDnsConfig(configured interface{}) *container.DNSConfig { + l := configured.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil + } + + config := l[0].(map[string]interface{}) + return &container.DNSConfig{ + ClusterDns: config["cluster_dns"].(string), + ClusterDnsScope: config["cluster_dns_scope"].(string), + ClusterDnsDomain: config["cluster_dns_domain"].(string), + } +} + func expandContainerClusterLoggingConfig(configured interface{}) *container.LoggingConfig { l := configured.([]interface{}) if len(l) == 0 || l[0] == nil { @@ -3316,6 +3363,19 @@ func flattenDatabaseEncryption(c *container.DatabaseEncryption) []map[string]int } } +func flattenDnsConfig(c *container.DNSConfig) []map[string]interface{} { + if c == nil { + return nil + } + return []map[string]interface{}{ + { + "cluster_dns": c.ClusterDns, + "cluster_dns_scope": c.ClusterDnsScope, + "cluster_dns_domain": c.ClusterDnsDomain, + }, + } +} + func flattenContainerClusterLoggingConfig(c *container.LoggingConfig) []map[string]interface{} { if c == nil { return nil diff --git a/google/resource_container_cluster_test.go b/google/resource_container_cluster_test.go index 63ab4bd78d5..61bd894b2e6 100644 --- a/google/resource_container_cluster_test.go +++ b/google/resource_container_cluster_test.go @@ -1818,6 +1818,28 @@ func TestAccContainerCluster_withIPv4Error(t *testing.T) { }) } +func TestAccContainerCluster_withDNSConfig(t *testing.T) { + t.Parallel() + + clusterName := fmt.Sprintf("tf-test-cluster-%s", randString(t, 10)) + domainName := fmt.Sprintf("tf-test-domain-%s", randString(t, 10)) + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContainerClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_withDNSConfig(clusterName, "CLOUD_DNS", domainName, "VPC_SCOPE"), + }, + { + ResourceName: "google_container_cluster.with_dns_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccContainerCluster_masterAuthorizedNetworksDisabled(t *testing.T, resource_name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resource_name] @@ -3770,6 +3792,21 @@ resource "google_container_cluster" "with_autopilot" { `, containerNetName, clusterName, location, enabled) } +func testAccContainerCluster_withDNSConfig(clusterName string, clusterDns string, clusterDnsDomain string, clusterDnsScope string) string { + return fmt.Sprintf(` +resource "google_container_cluster" "with_dns_config" { + name = "%s" + location = "us-central1-f" + initial_node_count = 1 + dns_config { + cluster_dns = "%s" + cluster_dns_domain = "%s" + cluster_dns_scope = "%s" + } +} +`, clusterName, clusterDns, clusterDnsDomain, clusterDnsScope) +} + func testAccContainerCluster_withLoggingConfigEnabled(name string) string { return fmt.Sprintf(` resource "google_container_cluster" "primary" { diff --git a/website/docs/r/container_cluster.html.markdown b/website/docs/r/container_cluster.html.markdown index 161cd3684d8..a238533726a 100644 --- a/website/docs/r/container_cluster.html.markdown +++ b/website/docs/r/container_cluster.html.markdown @@ -337,7 +337,7 @@ subnetwork in which the cluster's instances are launched. * `default_snat_status` - (Optional) [GKE SNAT](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent#how_ipmasq_works) DefaultSnatStatus contains the desired state of whether default sNAT should be disabled on the cluster, [API doc](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#networkconfig). Structure is [documented below](#nested_default_snat_status) -* `dns_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) +* `dns_config` - (Optional) Configuration for [Using Cloud DNS for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-dns). Structure is [documented below](#nested_dns_config). The `default_snat_status` block supports