Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloud Composer connection subnetwork #3912

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/5523.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
composer: added support for Private Service Connect by adding field `cloud_composer_connection_subnetwork` in `google_composer_environment`
```
125 changes: 60 additions & 65 deletions google-beta/resource_composer_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ var (
"config.0.environment_size",
}

composerPrivateEnvironmentConfig = []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
"config.0.private_environment_config.0.enable_privately_used_public_ips",
"config.0.private_environment_config.0.cloud_composer_connection_subnetwork",
}

composerIpAllocationPolicyKeys = []string{
"config.0.node_config.0.ip_allocation_policy.0.use_ip_aliases",
"config.0.node_config.0.ip_allocation_policy.0.cluster_secondary_range_name",
Expand Down Expand Up @@ -358,81 +368,60 @@ func resourceComposerEnvironment() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enable_private_endpoint": {
Type: schema.TypeBool,
Optional: true,
Default: true,
AtLeastOneOf: []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
},
ForceNew: true,
Description: `If true, access to the public endpoint of the GKE cluster is denied. If this field is set to true, ip_allocation_policy.use_ip_aliases must be set to true for Cloud Composer environments in versions composer-1.*.*-airflow-*.*.*.`,
Type: schema.TypeBool,
Optional: true,
Default: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `If true, access to the public endpoint of the GKE cluster is denied. If this field is set to true, ip_allocation_policy.use_ip_aliases must be set to true for Cloud Composer environments in versions composer-1.*.*-airflow-*.*.*.`,
},
"master_ipv4_cidr_block": {
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
},
ForceNew: true,
Description: `The IP range in CIDR notation to use for the hosted master network. This range is used for assigning internal IP addresses to the cluster master or set of masters and to the internal load balancer virtual IP. This range must not overlap with any other ranges in use within the cluster's network. If left blank, the default value of '172.16.0.0/28' is used.`,
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `The IP range in CIDR notation to use for the hosted master network. This range is used for assigning internal IP addresses to the cluster master or set of masters and to the internal load balancer virtual IP. This range must not overlap with any other ranges in use within the cluster's network. If left blank, the default value of '172.16.0.0/28' is used.`,
},
"web_server_ipv4_cidr_block": {
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
},
ForceNew: true,
Description: `The CIDR block from which IP range for web server will be reserved. Needs to be disjoint from master_ipv4_cidr_block and cloud_sql_ipv4_cidr_block. This field is supported for Cloud Composer environments in versions composer-1.*.*-airflow-*.*.*.`,
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `The CIDR block from which IP range for web server will be reserved. Needs to be disjoint from master_ipv4_cidr_block and cloud_sql_ipv4_cidr_block. This field is supported for Cloud Composer environments in versions composer-1.*.*-airflow-*.*.*.`,
},
"cloud_sql_ipv4_cidr_block": {
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
},
ForceNew: true,
Description: `The CIDR block from which IP range in tenant project will be reserved for Cloud SQL. Needs to be disjoint from web_server_ipv4_cidr_block.`,
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `The CIDR block from which IP range in tenant project will be reserved for Cloud SQL. Needs to be disjoint from web_server_ipv4_cidr_block.`,
},
"cloud_composer_network_ipv4_cidr_block": {
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: []string{
"config.0.private_environment_config.0.enable_private_endpoint",
"config.0.private_environment_config.0.master_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_sql_ipv4_cidr_block",
"config.0.private_environment_config.0.web_server_ipv4_cidr_block",
"config.0.private_environment_config.0.cloud_composer_network_ipv4_cidr_block",
},
ForceNew: true,
Description: `The CIDR block from which IP range for Cloud Composer Network in tenant project will be reserved. Needs to be disjoint from private_cluster_config.master_ipv4_cidr_block and cloud_sql_ipv4_cidr_block. This field is supported for Cloud Composer environments in versions composer-2.*.*-airflow-*.*.* and newer.`,
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `The CIDR block from which IP range for Cloud Composer Network in tenant project will be reserved. Needs to be disjoint from private_cluster_config.master_ipv4_cidr_block and cloud_sql_ipv4_cidr_block. This field is supported for Cloud Composer environments in versions composer-2.*.*-airflow-*.*.* and newer.`,
},
"enable_privately_used_public_ips": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
ForceNew: true,
Description: `When enabled, IPs from public (non-RFC1918) ranges can be used for ip_allocation_policy.cluster_ipv4_cidr_block and ip_allocation_policy.service_ipv4_cidr_block.`,
Type: schema.TypeBool,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `When enabled, IPs from public (non-RFC1918) ranges can be used for ip_allocation_policy.cluster_ipv4_cidr_block and ip_allocation_policy.service_ipv4_cidr_block.`,
},
"cloud_composer_connection_subnetwork": {
Type: schema.TypeString,
Optional: true,
Computed: true,
AtLeastOneOf: composerPrivateEnvironmentConfig,
ForceNew: true,
Description: `When specified, the environment will use Private Service Connect instead of VPC peerings to connect to Cloud SQL in the Tenant Project, and the PSC endpoint in the Customer Project will use an IP address from this subnetwork. This field is supported for Cloud Composer environments in versions composer-2.*.*-airflow-*.*.* and newer.`,
},
},
},
Expand Down Expand Up @@ -669,6 +658,7 @@ func resourceComposerEnvironment() *schema.Resource {
"environment_size": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: false,
AtLeastOneOf: composerConfigKeys,
ValidateFunc: validation.StringInSlice([]string{"ENVIRONMENT_SIZE_SMALL", "ENVIRONMENT_SIZE_MEDIUM", "ENVIRONMENT_SIZE_LARGE"}, false),
Expand Down Expand Up @@ -1218,6 +1208,7 @@ func flattenComposerEnvironmentConfigPrivateEnvironmentConfig(envCfg *composer.P
transformed["web_server_ipv4_cidr_block"] = envCfg.WebServerIpv4CidrBlock
transformed["cloud_composer_network_ipv4_cidr_block"] = envCfg.CloudComposerNetworkIpv4CidrBlock
transformed["enable_privately_used_public_ips"] = envCfg.EnablePrivatelyUsedPublicIps
transformed["cloud_composer_connection_subnetwork"] = envCfg.CloudComposerConnectionSubnetwork

return []interface{}{transformed}
}
Expand Down Expand Up @@ -1554,6 +1545,10 @@ func expandComposerEnvironmentConfigPrivateEnvironmentConfig(v interface{}, d *s
transformed.EnablePrivatelyUsedPublicIps = v.(bool)
}

if v, ok := original["cloud_composer_connection_subnetwork"]; ok {
transformed.CloudComposerConnectionSubnetwork = v.(string)
}

transformed.PrivateClusterConfig = subBlock

return transformed, nil
Expand Down
85 changes: 82 additions & 3 deletions google-beta/resource_composer_environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ func TestAccComposerEnvironment_ComposerV2(t *testing.T) {
envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, randInt(t))
network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, randInt(t))
subnetwork := network + "-1"

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Expand All @@ -393,6 +392,38 @@ func TestAccComposerEnvironment_ComposerV2(t *testing.T) {
})
}

func TestAccComposerEnvironment_composerV2PrivateServiceConnect(t *testing.T) {
t.Parallel()

envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, randInt(t))
network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, randInt(t))
subnetwork := network + "-1"
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccComposerEnvironmentDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComposerEnvironment_composerV2PrivateServiceConnect(envName, network, subnetwork),
},
{
ResourceName: "google_composer_environment.test",
ImportState: true,
ImportStateVerify: true,
},
// This is a terrible clean-up step in order to get destroy to succeed,
// due to dangling firewall rules left by the Composer Environment blocking network deletion.
// TODO(dzarmola): Remove this check if firewall rules bug gets fixed by Composer.
{
PlanOnly: true,
ExpectNonEmptyPlan: false,
Config: testAccComposerEnvironment_composerV2PrivateServiceConnect(envName, network, subnetwork),
Check: testAccCheckClearComposerEnvironmentFirewalls(t, network),
},
},
})
}

// Checks behavior of node config, including dependencies on Compute resources.
func TestAccComposerEnvironment_withNodeConfig(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -976,7 +1007,7 @@ locals {
}
resource "google_composer_environment" "test" {
name = "%s"
region = "us-central1"
region = "us-east1"

config {
node_config {
Expand All @@ -988,7 +1019,8 @@ resource "google_composer_environment" "test" {
}

software_config {
image_version = local.matching_images[0]
# image_version = local.matching_images[0]
image_version = "composer-2.0.0-preview.6-airflow-2.1.4"
}

maintenance_window {
Expand Down Expand Up @@ -1033,6 +1065,53 @@ resource "google_compute_network" "test" {
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "test" {
name = "%s"
ip_cidr_range = "10.2.0.0/16"
region = "us-east1"
network = google_compute_network.test.self_link
private_ip_google_access = true
}

`, envName, network, subnetwork)
}

func testAccComposerEnvironment_composerV2PrivateServiceConnect(envName, network, subnetwork string) string {
return fmt.Sprintf(`
data "google_composer_image_versions" "all" {
}

locals {
composer_version = "2" # both composer_version and airflow_version are parts of regex, so if either 1 or 2 version is ok "[12]" should be used,
airflow_version = "2" # if sub-version is needed remember to escape "." with "\\." for example 1.2 should be written as "1\\.2"
reg_ex = join("", ["composer-", local.composer_version, "\\.[\\d+\\.]*\\d+.*-airflow-", local.airflow_version, "\\.[\\d+\\.]*\\d+"])
matching_images = [for v in data.google_composer_image_versions.all.image_versions[*].image_version_id: v if length(regexall(local.reg_ex, v)) > 0]
}
resource "google_composer_environment" "test" {
name = "%s"
region = "us-central1"

config {
node_config {
network = google_compute_network.test.self_link
subnetwork = google_compute_subnetwork.test.self_link
}

software_config {
image_version = local.matching_images[0]
}
private_environment_config {
cloud_composer_connection_subnetwork = google_compute_subnetwork.test.self_link
}
}

}

resource "google_compute_network" "test" {
name = "%s"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "test" {
name = "%s"
ip_cidr_range = "10.2.0.0/16"
Expand Down
7 changes: 7 additions & 0 deletions website/docs/r/composer_environment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,13 @@ See [documentation](https://cloud.google.com/composer/docs/how-to/managing/confi
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
When enabled, IPs from public (non-RFC1918) ranges can be used for
`ip_allocation_policy.cluster_ipv4_cidr_block` and `ip_allocation_policy.service_ipv4_cidr_block`.

* `cloud_composer_connection_subnetwork"` -
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
When specified, the environment will use Private Service Connect instead of VPC peerings to connect
to Cloud SQL in the Tenant Project, and the PSC endpoint in the Customer Project will use an IP
address from this subnetwork. This field is supported for Cloud Composer environments in
versions `composer-2.*.*-airflow-*.*.*` and newer.


The `ip_allocation_policy` block supports:
Expand Down