Skip to content

Commit 9deadb0

Browse files
New fields: enable_private_environment, enable_private_builds_only (#9689) (#6870)
* add enable_private_environment and enable_private_builds_only configs * add tests * correction in config name * remove unnecessary checks * case that PrivateEnvironmentConfig is nil * add edge case tests for composer 3 * make new fields beta only * add docs * correct merge mistake * avoid false negative for enablePrivateEnvironment * check image version to avoid overriding EnablePrivateEnvironment * minor fixes * simplify code [upstream:8df5516b9f3d17877b0cd046563352c0ded6c2a1] Signed-off-by: Modular Magician <[email protected]>
1 parent f4281ef commit 9deadb0

File tree

4 files changed

+188
-3
lines changed

4 files changed

+188
-3
lines changed

.changelog/9689.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
composer: added fields `enable_private_environment` and `enable_private_builds_only` to `google_composer_environment`
3+
```

google-beta/services/composer/resource_composer_environment.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ var (
7070
"config.0.environment_size",
7171
"config.0.master_authorized_networks_config",
7272
"config.0.resilience_mode",
73+
"config.0.enable_private_environment",
74+
"config.0.enable_private_builds_only",
7375
}
7476

7577
recoveryConfigKeys = []string{
@@ -559,6 +561,22 @@ func ResourceComposerEnvironment() *schema.Resource {
559561
},
560562
},
561563
},
564+
"enable_private_environment": {
565+
Type: schema.TypeBool,
566+
Computed: true,
567+
Optional: true,
568+
ForceNew: false,
569+
AtLeastOneOf: composerConfigKeys,
570+
Description: `Optional. If true, a private Composer environment will be created.`,
571+
},
572+
"enable_private_builds_only": {
573+
Type: schema.TypeBool,
574+
Computed: true,
575+
Optional: true,
576+
ForceNew: false,
577+
AtLeastOneOf: composerConfigKeys,
578+
Description: `Optional. If true, builds performed during operations that install Python packages have only private connectivity to Google services. If false, the builds also have access to the internet.`,
579+
},
562580
"web_server_network_access_control": {
563581
Type: schema.TypeList,
564582
Optional: true,
@@ -1221,6 +1239,33 @@ func resourceComposerEnvironmentUpdate(d *schema.ResourceData, meta interface{})
12211239
}
12221240
}
12231241

1242+
if d.HasChange("config.0.enable_private_environment") {
1243+
patchObj := &composer.Environment{
1244+
Config: &composer.EnvironmentConfig{
1245+
PrivateEnvironmentConfig: &composer.PrivateEnvironmentConfig{},
1246+
},
1247+
}
1248+
if config != nil && config.PrivateEnvironmentConfig != nil {
1249+
patchObj.Config.PrivateEnvironmentConfig.EnablePrivateEnvironment = config.PrivateEnvironmentConfig.EnablePrivateEnvironment
1250+
}
1251+
err = resourceComposerEnvironmentPatchField("config.PrivateEnvironmentConfig.EnablePrivateEnvironment", userAgent, patchObj, d, tfConfig)
1252+
if err != nil {
1253+
return err
1254+
}
1255+
}
1256+
1257+
if d.HasChange("config.0.enable_private_builds_only") {
1258+
patchObj := &composer.Environment{
1259+
Config: &composer.EnvironmentConfig{
1260+
PrivateEnvironmentConfig: &composer.PrivateEnvironmentConfig{},
1261+
},
1262+
}
1263+
if config != nil && config.PrivateEnvironmentConfig != nil {
1264+
patchObj.Config.PrivateEnvironmentConfig.EnablePrivateBuildsOnly = config.PrivateEnvironmentConfig.EnablePrivateBuildsOnly
1265+
}
1266+
err = resourceComposerEnvironmentPatchField("config.PrivateEnvironmentConfig.EnablePrivateBuildsOnly", userAgent, patchObj, d, tfConfig)
1267+
}
1268+
12241269
if d.HasChange("config.0.software_config.0.web_server_plugins_mode") {
12251270
patchObj := &composer.Environment{
12261271
Config: &composer.EnvironmentConfig{
@@ -1476,6 +1521,8 @@ func flattenComposerEnvironmentConfig(envCfg *composer.EnvironmentConfig) interf
14761521
transformed["node_config"] = flattenComposerEnvironmentConfigNodeConfig(envCfg.NodeConfig)
14771522
transformed["software_config"] = flattenComposerEnvironmentConfigSoftwareConfig(envCfg.SoftwareConfig)
14781523
transformed["private_environment_config"] = flattenComposerEnvironmentConfigPrivateEnvironmentConfig(envCfg.PrivateEnvironmentConfig)
1524+
transformed["enable_private_environment"] = envCfg.PrivateEnvironmentConfig.EnablePrivateEnvironment
1525+
transformed["enable_private_builds_only"] = envCfg.PrivateEnvironmentConfig.EnablePrivateBuildsOnly
14791526
transformed["web_server_network_access_control"] = flattenComposerEnvironmentConfigWebServerNetworkAccessControl(envCfg.WebServerNetworkAccessControl)
14801527
transformed["database_config"] = flattenComposerEnvironmentConfigDatabaseConfig(envCfg.DatabaseConfig)
14811528
transformed["web_server_config"] = flattenComposerEnvironmentConfigWebServerConfig(envCfg.WebServerConfig)
@@ -1815,6 +1862,21 @@ func expandComposerEnvironmentConfig(v interface{}, d *schema.ResourceData, conf
18151862
}
18161863
transformed.PrivateEnvironmentConfig = transformedPrivateEnvironmentConfig
18171864

1865+
/*
1866+
config.enable_private_environment in terraform maps to
1867+
composer.PrivateEnvironmentConfig.EnablePrivateEnvironment in API.
1868+
Check image version to avoid overriding EnablePrivateEnvironment in case of other versions.
1869+
*/
1870+
if isComposer3(d, config) {
1871+
transformed.PrivateEnvironmentConfig = &composer.PrivateEnvironmentConfig{}
1872+
if enablePrivateEnvironmentRaw, ok := original["enable_private_environment"]; ok {
1873+
transformed.PrivateEnvironmentConfig.EnablePrivateEnvironment = enablePrivateEnvironmentRaw.(bool)
1874+
}
1875+
if enablePrivateBuildsOnlyRaw, ok := original["enable_private_builds_only"]; ok {
1876+
transformed.PrivateEnvironmentConfig.EnablePrivateBuildsOnly = enablePrivateBuildsOnlyRaw.(bool)
1877+
}
1878+
}
1879+
18181880
transformedWebServerNetworkAccessControl, err := expandComposerEnvironmentConfigWebServerNetworkAccessControl(original["web_server_network_access_control"], d, config)
18191881
if err != nil {
18201882
return nil, err
@@ -2688,3 +2750,8 @@ func versionsEqual(old, new string) (bool, error) {
26882750
}
26892751
return o.Equal(n), nil
26902752
}
2753+
2754+
func isComposer3(d *schema.ResourceData, config *transport_tpg.Config) bool {
2755+
image_version := d.Get("config.0.software_config.0.image_version").(string)
2756+
return strings.Contains(image_version, "composer-3")
2757+
}

google-beta/services/composer/resource_composer_environment_test.go

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,80 @@ func TestAccComposerEnvironmentComposer3_update(t *testing.T) {
11831183
})
11841184
}
11851185

1186+
// Checks Composer 3 specific updatable fields.
1187+
func TestAccComposerEnvironmentComposer3_updateToEmpty(t *testing.T) {
1188+
t.Parallel()
1189+
1190+
envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, acctest.RandInt(t))
1191+
network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, acctest.RandInt(t))
1192+
subnetwork := network + "-1"
1193+
1194+
acctest.VcrTest(t, resource.TestCase{
1195+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1196+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1197+
CheckDestroy: testAccComposerEnvironmentDestroyProducer(t),
1198+
Steps: []resource.TestStep{
1199+
{
1200+
Config: testAccComposerEnvironmentComposer3_basic(envName, network, subnetwork),
1201+
},
1202+
{
1203+
Config: testAccComposerEnvironmentComposer3_empty(envName, network, subnetwork),
1204+
},
1205+
{
1206+
ResourceName: "google_composer_environment.test",
1207+
ImportState: true,
1208+
ImportStateVerify: true,
1209+
},
1210+
// This is a terrible clean-up step in order to get destroy to succeed,
1211+
// due to dangling firewall rules left by the Composer Environment blocking network deletion.
1212+
// TODO: Remove this check if firewall rules bug gets fixed by Composer.
1213+
{
1214+
PlanOnly: true,
1215+
ExpectNonEmptyPlan: false,
1216+
Config: testAccComposerEnvironmentComposer3_empty(envName, network, subnetwork),
1217+
Check: testAccCheckClearComposerEnvironmentFirewalls(t, network),
1218+
},
1219+
},
1220+
})
1221+
}
1222+
1223+
// Checks Composer 3 specific updatable fields.
1224+
func TestAccComposerEnvironmentComposer3_updateFromEmpty(t *testing.T) {
1225+
t.Parallel()
1226+
1227+
envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, acctest.RandInt(t))
1228+
network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, acctest.RandInt(t))
1229+
subnetwork := network + "-1"
1230+
1231+
acctest.VcrTest(t, resource.TestCase{
1232+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1233+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1234+
CheckDestroy: testAccComposerEnvironmentDestroyProducer(t),
1235+
Steps: []resource.TestStep{
1236+
{
1237+
Config: testAccComposerEnvironmentComposer3_empty(envName, network, subnetwork),
1238+
},
1239+
{
1240+
Config: testAccComposerEnvironmentComposer3_update(envName, network, subnetwork),
1241+
},
1242+
{
1243+
ResourceName: "google_composer_environment.test",
1244+
ImportState: true,
1245+
ImportStateVerify: true,
1246+
},
1247+
// This is a terrible clean-up step in order to get destroy to succeed,
1248+
// due to dangling firewall rules left by the Composer Environment blocking network deletion.
1249+
// TODO: Remove this check if firewall rules bug gets fixed by Composer.
1250+
{
1251+
PlanOnly: true,
1252+
ExpectNonEmptyPlan: false,
1253+
Config: testAccComposerEnvironmentComposer3_update(envName, network, subnetwork),
1254+
Check: testAccCheckClearComposerEnvironmentFirewalls(t, network),
1255+
},
1256+
},
1257+
})
1258+
}
1259+
11861260
func testAccComposerEnvironment_customBucket(bucketName, envName, network, subnetwork string) string {
11871261
return fmt.Sprintf(`
11881262
resource "google_storage_bucket" "test" {
@@ -2733,6 +2807,34 @@ resource "google_project_iam_member" "composer-worker" {
27332807
`, environment, network, subnetwork, serviceAccount)
27342808
}
27352809

2810+
func testAccComposerEnvironmentComposer3_empty(name, network, subnetwork string) string {
2811+
return fmt.Sprintf(`
2812+
resource "google_composer_environment" "test" {
2813+
name = "%s"
2814+
region = "us-central1"
2815+
config {
2816+
software_config {
2817+
image_version = "composer-3-airflow-2"
2818+
}
2819+
}
2820+
}
2821+
2822+
// use a separate network to avoid conflicts with other tests running in parallel
2823+
// that use the default network/subnet
2824+
resource "google_compute_network" "test" {
2825+
name = "%s"
2826+
auto_create_subnetworks = false
2827+
}
2828+
2829+
resource "google_compute_subnetwork" "test" {
2830+
name = "%s"
2831+
ip_cidr_range = "10.2.0.0/16"
2832+
region = "us-central1"
2833+
network = google_compute_network.test.self_link
2834+
}
2835+
`, name, network, subnetwork)
2836+
}
2837+
27362838
func testAccComposerEnvironmentComposer3_basic(name, network, subnetwork string) string {
27372839
return fmt.Sprintf(`
27382840
resource "google_composer_environment" "test" {
@@ -2752,6 +2854,8 @@ resource "google_composer_environment" "test" {
27522854
storage_gb = 2
27532855
}
27542856
}
2857+
enable_private_environment = true
2858+
enable_private_builds_only = true
27552859
}
27562860
}
27572861
@@ -2777,20 +2881,22 @@ resource "google_composer_environment" "test" {
27772881
name = "%s"
27782882
region = "us-central1"
27792883
config {
2884+
node_config {
2885+
composer_internal_ipv4_cidr_block = "100.64.128.0/20"
2886+
}
27802887
software_config {
27812888
web_server_plugins_mode = "DISABLED"
27822889
image_version = "composer-3-airflow-2"
27832890
}
2784-
node_config {
2785-
composer_internal_ipv4_cidr_block = "100.64.128.0/20"
2786-
}
27872891
workloads_config {
27882892
dag_processor {
27892893
cpu = 2
27902894
memory_gb = 2
27912895
storage_gb = 1
27922896
}
27932897
}
2898+
enable_private_environment = false
2899+
enable_private_builds_only = false
27942900
}
27952901
}
27962902

website/docs/r/composer_environment.html.markdown

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ The following arguments are supported:
282282
(Optional)
283283
The configuration used for the Private IP Cloud Composer environment. Structure is [documented below](#nested_private_environment_config).
284284

285+
* `enable_private_environment` -
286+
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html), Cloud Composer 3 only)
287+
If true, a private Composer environment will be created.
288+
289+
* `enable_private_builds_only` -
290+
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html), Cloud Composer 3 only)
291+
If true, builds performed during operations that install Python packages have only private connectivity to Google services.
292+
If false, the builds also have access to the internet.
293+
285294
* `web_server_network_access_control` -
286295
The network-level access control policy for the Airflow web server.
287296
If unspecified, no network-level access restrictions are applied.

0 commit comments

Comments
 (0)